mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-23 11:30:23 +10:00
Moving Xmonad to config folder breaks things. It needs to be in HOME.
This commit is contained in:
1084
.xmonad/README.org
Normal file
1084
.xmonad/README.org
Normal file
File diff suppressed because it is too large
Load Diff
10
.xmonad/pacman-hooks/recompile-xmonad.hook
Normal file
10
.xmonad/pacman-hooks/recompile-xmonad.hook
Normal file
@@ -0,0 +1,10 @@
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = xmonad*
|
||||
|
||||
[Action]
|
||||
Description = Recompiling Xmonad now because of Xmonad updates...
|
||||
When = PostTransaction
|
||||
Depends = xmonad
|
||||
Exec = /bin/sh -c "runuser -l $( who | cut -d ' ' -f1 | uniq) -c 'xmonad --recompile'"
|
||||
10
.xmonad/pacman-hooks/recompile-xmonadh.hook
Normal file
10
.xmonad/pacman-hooks/recompile-xmonadh.hook
Normal file
@@ -0,0 +1,10 @@
|
||||
[Trigger]
|
||||
Operation = Upgrade
|
||||
Type = Package
|
||||
Target = haskell*
|
||||
|
||||
[Action]
|
||||
Description = Recompiling Xmonad now because of Haskell updates ...
|
||||
When = PostTransaction
|
||||
Depends = xmonad
|
||||
Exec = /bin/sh -c "runuser -l $( who | cut -d ' ' -f1 | uniq) -c 'xmonad --recompile'"
|
||||
@@ -0,0 +1,851 @@
|
||||
-- Xmonad is a dynamically tiling X11 window manager that is written and
|
||||
-- configured in Haskell. Official documentation: https://xmonad.org
|
||||
|
||||
-- This is the xmonad configuration of Derek Taylor (DistroTube)
|
||||
-- My YouTube: http://www.youtube.com/c/DistroTube
|
||||
-- My GitLab: http://www.gitlab.com/dwt1/
|
||||
|
||||
-- This config is massively long. It is purposely bloated with a ton of
|
||||
-- examples of what you can do with xmonad. It is written more as a
|
||||
-- study guide rather than a config that you should download and use.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- IMPORTS
|
||||
------------------------------------------------------------------------
|
||||
-- Base
|
||||
import XMonad
|
||||
import System.Exit (exitSuccess)
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
-- Actions
|
||||
import XMonad.Actions.CopyWindow (kill1, killAllOtherCopies)
|
||||
import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Actions.MouseResize
|
||||
import XMonad.Actions.Promote
|
||||
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
|
||||
import qualified XMonad.Actions.TreeSelect as TS
|
||||
import XMonad.Actions.WindowGo (runOrRaise)
|
||||
import XMonad.Actions.WithAll (sinkAll, killAll)
|
||||
import qualified XMonad.Actions.Search as S
|
||||
|
||||
-- Data
|
||||
import Data.Char (isSpace)
|
||||
import Data.Monoid
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Tree
|
||||
import qualified Data.Tuple.Extra as TE
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- Hooks
|
||||
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, PP(..))
|
||||
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
|
||||
import XMonad.Hooks.FadeInactive
|
||||
import XMonad.Hooks.ManageDocks (avoidStruts, docks, docksEventHook, ToggleStruts(..))
|
||||
import XMonad.Hooks.ServerMode
|
||||
import XMonad.Hooks.SetWMName
|
||||
|
||||
-- Layouts
|
||||
import XMonad.Layout.GridVariants (Grid(Grid))
|
||||
import XMonad.Layout.SimplestFloat
|
||||
import XMonad.Layout.Spiral
|
||||
import XMonad.Layout.ResizableTile
|
||||
import XMonad.Layout.Tabbed
|
||||
import XMonad.Layout.ThreeColumns
|
||||
|
||||
-- Layouts modifiers
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
|
||||
import XMonad.Layout.Magnifier
|
||||
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
|
||||
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.Renamed (renamed, Rename(Replace))
|
||||
import XMonad.Layout.ShowWName
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
|
||||
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
|
||||
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
|
||||
|
||||
-- Prompt
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.Input
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Man
|
||||
import XMonad.Prompt.Pass
|
||||
import XMonad.Prompt.Shell (shellPrompt)
|
||||
import XMonad.Prompt.Ssh
|
||||
import XMonad.Prompt.XMonad
|
||||
import Control.Arrow (first)
|
||||
|
||||
-- Utilities
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Util.Run (runProcessWithInput, safeSpawn)
|
||||
import XMonad.Util.SpawnOnce
|
||||
|
||||
-- For polybar
|
||||
import qualified DBus as D
|
||||
import qualified DBus.Client as D
|
||||
import qualified Codec.Binary.UTF8.String as UTF8
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- VARIABLES
|
||||
------------------------------------------------------------------------
|
||||
-- It's nice to assign values to stuff that you will use more than once
|
||||
-- in the config. Setting values for things like font, terminal and editor
|
||||
-- means you only have to change the value here to make changes globally.
|
||||
myFont :: String
|
||||
myFont = "xft:Mononoki Nerd Font:bold:size=9"
|
||||
|
||||
myModMask :: KeyMask
|
||||
myModMask = mod4Mask -- Sets modkey to super/windows key
|
||||
|
||||
myTerminal :: String
|
||||
myTerminal = "alacritty" -- Sets default terminal
|
||||
|
||||
myBrowser :: String
|
||||
myBrowser = myTerminal ++ " -e lynx " -- Sets lynx as browser for tree select
|
||||
-- myBrowser = "firefox " -- Sets firefox as browser for tree select
|
||||
|
||||
myEditor :: String
|
||||
myEditor = "emacsclient -c -a emacs " -- Sets emacs as editor for tree select
|
||||
-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor for tree select
|
||||
|
||||
myBorderWidth :: Dimension
|
||||
myBorderWidth = 2 -- Sets border width for windows
|
||||
|
||||
myNormColor :: String
|
||||
myNormColor = "#292d3e" -- Border color of normal windows
|
||||
|
||||
myFocusColor :: String
|
||||
myFocusColor = "#bbc5ff" -- Border color of focused windows
|
||||
|
||||
altMask :: KeyMask
|
||||
altMask = mod1Mask -- Setting this for use in xprompts
|
||||
|
||||
-- Colors for polybar
|
||||
color1, color2, color3, color4 :: String
|
||||
color1 = "#7F7F7F"
|
||||
color2 = "#c792ea"
|
||||
color3 = "#900000"
|
||||
color4 = "#2E9AFE"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- AUTOSTART
|
||||
------------------------------------------------------------------------
|
||||
myStartupHook :: X ()
|
||||
myStartupHook = do
|
||||
spawnOnce "nitrogen --restore &"
|
||||
spawnOnce "picom &"
|
||||
spawnOnce "/usr/bin/emacs --daemon &"
|
||||
spawnOnce "/home/dt/.config/polybar/launch-xmonad.sh &"
|
||||
setWMName "LG3D"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- GRID SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- GridSelect displays items (programs, open windows, etc.) in a 2D grid
|
||||
-- and lets the user select from it with the cursor/hjkl keys or the mouse.
|
||||
myColorizer :: Window -> Bool -> X (String, String)
|
||||
myColorizer = colorRangeFromClassName
|
||||
(0x29,0x2d,0x3e) -- lowest inactive bg
|
||||
(0x29,0x2d,0x3e) -- highest inactive bg
|
||||
(0xc7,0x92,0xea) -- active bg
|
||||
(0xc0,0xa7,0x9a) -- inactive fg
|
||||
(0x29,0x2d,0x3e) -- active fg
|
||||
|
||||
-- gridSelect menu layout
|
||||
mygridConfig :: p -> GSConfig Window
|
||||
mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
spawnSelected' :: [(String, String)] -> X ()
|
||||
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
|
||||
where conf = def
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
-- The lists below are actually 3-tuples for use with gridSelect and treeSelect.
|
||||
-- TreeSelect uses all three values in the 3-tuples but GridSelect only needs first
|
||||
-- two values in each list (see myAppGrid, myBookmarkGrid and myConfigGrid below).
|
||||
myApplications :: [(String, String, String)]
|
||||
myApplications = [ ("Audacity", "audacity", "Graphical cross-platform audio eidtor")
|
||||
, ("Deadbeef", "deadbeef", "Lightweight GUI audio player")
|
||||
, ("Emacs", "emacs", "Much more than a text editor")
|
||||
, ("Firefox", "firefox", "The famous open source web browser")
|
||||
, ("Geany", "geany", "A nice text editor")
|
||||
, ("Geary", "geary", "Email client that is attractive")
|
||||
, ("Gimp", "gimp", "Open source alternative to Photoshop")
|
||||
, ("Kdenlive", "kdenlive", "A great open source video editor")
|
||||
, ("LibreOffice Impress", "loimpress", "For making presentations")
|
||||
, ("LibreOffice Writer", "lowriter", "A fully featured word processor")
|
||||
, ("OBS", "obs", "Open broadcaster software")
|
||||
, ("PCManFM", "pcmanfm", "Lightweight graphical file manager")
|
||||
, ("Simple Terminal", "st", "Suckless simple terminal")
|
||||
, ("Steam", "steam", "Proprietary gaming platform")
|
||||
, ("Surf Browser", "surf suckless.org", "Suckless surf web browser")
|
||||
, ("Xonotic", "xonotic-glx", "A fast-paced first person shooter")
|
||||
]
|
||||
|
||||
myBookmarks :: [(String, String, String)]
|
||||
myBookmarks = [ ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
]
|
||||
|
||||
myConfigs :: [(String, String, String)]
|
||||
myConfigs = [ ("bashrc", myEditor ++ "/home/dt/.bashrc", "the bourne again shell")
|
||||
, ("doom emacs config.el", myEditor ++ "/home/dt/.doom.d/config.el", "doom emacs config")
|
||||
, ("doom emacs init.el", myEditor ++ "/home/dt/.doom.d/init.el", "doom emacs init")
|
||||
, ("dwm", myEditor ++ "/home/dt/dwm-distrotube/config.h", "dwm config file")
|
||||
, ("qtile", myEditor ++ "/home/dt/.config/qtile/config.py", "qtile config")
|
||||
, ("xmonad.hs", myEditor ++ "/home/dt/.xmonad/xmonad.hs", "xmonad config")
|
||||
, ("zshrc", myEditor ++ "/home/dt/.zshrc", "config for the z shell")
|
||||
]
|
||||
|
||||
-- Let's take myApplications, myBookmarks and myConfigs and take only
|
||||
-- the first two values from those 3-tuples (for GridSelect).
|
||||
myAppGrid :: [(String, String)]
|
||||
myAppGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myApplications
|
||||
|
||||
myBookmarkGrid :: [(String, String)]
|
||||
myBookmarkGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myBookmarks
|
||||
|
||||
myConfigGrid :: [(String, String)]
|
||||
myConfigGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myConfigs
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- TREE SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- TreeSelect displays your workspaces or actions in a Tree-like format.
|
||||
-- You can select desired workspace/action with the cursor or hjkl keys.
|
||||
|
||||
treeselectAction :: TS.TSConfig (X ()) -> X ()
|
||||
treeselectAction a = TS.treeselectAction a
|
||||
[ Node (TS.TSNode "applications" "a list of programs I use often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myApplications !! n)
|
||||
(TE.thd3 $ myApplications !! n)
|
||||
(spawn $ TE.snd3 $ myApplications !! n)
|
||||
) [] | n <- [0..(length myApplications - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "bookmarks" "a list of web bookmarks" (return ()))
|
||||
[Node (TS.TSNode(TE.fst3 $ myBookmarks !! n)
|
||||
(TE.thd3 $ myBookmarks !! n)
|
||||
(spawn $ TE.snd3 $ myBookmarks !! n)
|
||||
) [] | n <- [0..(length myBookmarks - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "config files" "config files that edit often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myConfigs !! n)
|
||||
(TE.thd3 $ myConfigs !! n)
|
||||
(spawn $ TE.snd3 $ myConfigs !! n)
|
||||
) [] | n <- [0..(length myConfigs - 1)]
|
||||
]
|
||||
]
|
||||
|
||||
-- Configuration options for treeSelect
|
||||
tsDefaultConfig :: TS.TSConfig a
|
||||
tsDefaultConfig = TS.TSConfig { TS.ts_hidechildren = True
|
||||
, TS.ts_background = 0xdd292d3e
|
||||
, TS.ts_font = myFont
|
||||
, TS.ts_node = (0xffd0d0d0, 0xff202331)
|
||||
, TS.ts_nodealt = (0xffd0d0d0, 0xff292d3e)
|
||||
, TS.ts_highlight = (0xffffffff, 0xff755999)
|
||||
, TS.ts_extra = 0xffd0d0d0
|
||||
, TS.ts_node_width = 200
|
||||
, TS.ts_node_height = 20
|
||||
, TS.ts_originX = 0
|
||||
, TS.ts_originY = 0
|
||||
, TS.ts_indent = 80
|
||||
, TS.ts_navigate = myTreeNavigation
|
||||
}
|
||||
|
||||
-- Keybindings for treeSelect menus. Use h-j-k-l to navigate.
|
||||
-- Use 'o' and 'i' to move forward/back in the workspace history.
|
||||
-- Single KEY's are for top-level nodes. SUPER+KEY are for the
|
||||
-- second-level nodes. SUPER+ALT+KEY are third-level nodes.
|
||||
myTreeNavigation = M.fromList
|
||||
[ ((0, xK_Escape), TS.cancel)
|
||||
, ((0, xK_Return), TS.select)
|
||||
, ((0, xK_space), TS.select)
|
||||
, ((0, xK_Up), TS.movePrev)
|
||||
, ((0, xK_Down), TS.moveNext)
|
||||
, ((0, xK_Left), TS.moveParent)
|
||||
, ((0, xK_Right), TS.moveChild)
|
||||
, ((0, xK_k), TS.movePrev)
|
||||
, ((0, xK_j), TS.moveNext)
|
||||
, ((0, xK_h), TS.moveParent)
|
||||
, ((0, xK_l), TS.moveChild)
|
||||
, ((0, xK_o), TS.moveHistBack)
|
||||
, ((0, xK_i), TS.moveHistForward)
|
||||
, ((0, xK_d), TS.moveTo ["dev"])
|
||||
, ((0, xK_g), TS.moveTo ["graphics"])
|
||||
, ((0, xK_m), TS.moveTo ["music"])
|
||||
, ((0, xK_v), TS.moveTo ["video"])
|
||||
, ((0, xK_w), TS.moveTo ["web"])
|
||||
, ((mod4Mask, xK_b), TS.moveTo ["web", "browser"])
|
||||
, ((mod4Mask, xK_c), TS.moveTo ["web", "chat"])
|
||||
, ((mod4Mask, xK_m), TS.moveTo ["web", "email"])
|
||||
, ((mod4Mask, xK_r), TS.moveTo ["web", "rss"])
|
||||
, ((mod4Mask, xK_w), TS.moveTo ["web", "web conference"])
|
||||
, ((mod4Mask, xK_d), TS.moveTo ["dev", "docs"])
|
||||
, ((mod4Mask, xK_e), TS.moveTo ["dev", "emacs"])
|
||||
, ((mod4Mask, xK_f), TS.moveTo ["dev", "files"])
|
||||
, ((mod4Mask, xK_p), TS.moveTo ["dev", "programming"])
|
||||
, ((mod4Mask, xK_t), TS.moveTo ["dev", "terminal"])
|
||||
, ((mod4Mask, xK_z), TS.moveTo ["dev", "virtualization"])
|
||||
, ((mod4Mask, xK_g), TS.moveTo ["graphics", "gimp"])
|
||||
, ((mod4Mask, xK_i), TS.moveTo ["graphics", "image viewer"])
|
||||
, ((mod4Mask, xK_a), TS.moveTo ["music", "audio editor"])
|
||||
, ((mod4Mask, xK_u), TS.moveTo ["music", "music player"])
|
||||
, ((mod4Mask, xK_o), TS.moveTo ["video", "obs"])
|
||||
, ((mod4Mask, xK_v), TS.moveTo ["video", "video player"])
|
||||
, ((mod4Mask, xK_k), TS.moveTo ["video", "kdenlive"])
|
||||
, ((mod4Mask .|. altMask, xK_h), TS.moveTo ["dev", "programming", "haskell"])
|
||||
, ((mod4Mask .|. altMask, xK_p), TS.moveTo ["dev", "programming", "python"])
|
||||
, ((mod4Mask .|. altMask, xK_s), TS.moveTo ["dev", "programming", "shell"])
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT SETTINGS
|
||||
------------------------------------------------------------------------
|
||||
dtXPConfig :: XPConfig
|
||||
dtXPConfig = def
|
||||
{ font = myFont
|
||||
, bgColor = "#292d3e"
|
||||
, fgColor = "#d0d0d0"
|
||||
, bgHLight = "#c792ea"
|
||||
, fgHLight = "#000000"
|
||||
, borderColor = "#535974"
|
||||
, promptBorderWidth = 0
|
||||
, promptKeymap = dtXPKeymap
|
||||
, position = Top
|
||||
-- , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.3 }
|
||||
, height = 20
|
||||
, historySize = 256
|
||||
, historyFilter = id
|
||||
, defaultText = []
|
||||
, autoComplete = Just 100000 -- set Just 100000 for .1 sec
|
||||
, showCompletionOnTab = False
|
||||
-- , searchPredicate = isPrefixOf
|
||||
, searchPredicate = fuzzyMatch
|
||||
, alwaysHighlight = True
|
||||
, maxComplRows = Nothing -- set to Just 5 for 5 rows
|
||||
}
|
||||
|
||||
-- The same config above minus the autocomplete feature which is annoying
|
||||
-- on certain Xprompts, like the search engine prompts.
|
||||
dtXPConfig' :: XPConfig
|
||||
dtXPConfig' = dtXPConfig
|
||||
{ autoComplete = Nothing
|
||||
}
|
||||
|
||||
-- A list of all of the standard Xmonad prompts and a key press assigned to them.
|
||||
-- These are used in conjunction with keybinding I set later in the config.
|
||||
promptList :: [(String, XPConfig -> X ())]
|
||||
promptList = [ ("m", manPrompt) -- manpages prompt
|
||||
, ("p", passPrompt) -- get passwords (requires 'pass')
|
||||
, ("g", passGeneratePrompt) -- generate passwords (requires 'pass')
|
||||
, ("r", passRemovePrompt) -- remove passwords (requires 'pass')
|
||||
, ("s", sshPrompt) -- ssh prompt
|
||||
, ("x", xmonadPrompt) -- xmonad prompt
|
||||
]
|
||||
|
||||
-- Same as the above list except this is for my custom prompts.
|
||||
promptList' :: [(String, XPConfig -> String -> X (), String)]
|
||||
promptList' = [ ("c", calcPrompt, "qalc") -- requires qalculate-gtk
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- CUSTOM PROMPTS
|
||||
------------------------------------------------------------------------
|
||||
-- calcPrompt requires a cli calculator called qalcualte-gtk.
|
||||
-- You could use this as a template for other custom prompts that
|
||||
-- use command line programs that return a single line of output.
|
||||
calcPrompt :: XPConfig -> String -> X ()
|
||||
calcPrompt c ans =
|
||||
inputPrompt c (trim ans) ?+ \input ->
|
||||
liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c
|
||||
where
|
||||
trim = f . f
|
||||
where f = reverse . dropWhile isSpace
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT KEYMAP (emacs-like key bindings for xprompts)
|
||||
------------------------------------------------------------------------
|
||||
dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ())
|
||||
dtXPKeymap = M.fromList $
|
||||
map (first $ (,) controlMask) -- control + <key>
|
||||
[ (xK_z, killBefore) -- kill line backwards
|
||||
, (xK_k, killAfter) -- kill line forwards
|
||||
, (xK_a, startOfLine) -- move to the beginning of the line
|
||||
, (xK_e, endOfLine) -- move to the end of the line
|
||||
, (xK_m, deleteString Next) -- delete a character foward
|
||||
, (xK_b, moveCursor Prev) -- move cursor forward
|
||||
, (xK_f, moveCursor Next) -- move cursor backward
|
||||
, (xK_BackSpace, killWord Prev) -- kill the previous word
|
||||
, (xK_y, pasteString) -- paste a string
|
||||
, (xK_g, quit) -- quit out of prompt
|
||||
, (xK_bracketleft, quit)
|
||||
]
|
||||
++
|
||||
map (first $ (,) altMask) -- meta key + <key>
|
||||
[ (xK_BackSpace, killWord Prev) -- kill the prev word
|
||||
, (xK_f, moveWord Next) -- move a word forward
|
||||
, (xK_b, moveWord Prev) -- move a word backward
|
||||
, (xK_d, killWord Next) -- kill the next word
|
||||
, (xK_n, moveHistory W.focusUp') -- move up thru history
|
||||
, (xK_p, moveHistory W.focusDown') -- move down thru history
|
||||
]
|
||||
++
|
||||
map (first $ (,) 0) -- <key>
|
||||
[ (xK_Return, setSuccess True >> setDone True)
|
||||
, (xK_KP_Enter, setSuccess True >> setDone True)
|
||||
, (xK_BackSpace, deleteString Prev)
|
||||
, (xK_Delete, deleteString Next)
|
||||
, (xK_Left, moveCursor Prev)
|
||||
, (xK_Right, moveCursor Next)
|
||||
, (xK_Home, startOfLine)
|
||||
, (xK_End, endOfLine)
|
||||
, (xK_Down, moveHistory W.focusUp')
|
||||
, (xK_Up, moveHistory W.focusDown')
|
||||
, (xK_Escape, quit)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SEARCH ENGINES
|
||||
------------------------------------------------------------------------
|
||||
-- Xmonad has several search engines available to use located in
|
||||
-- XMonad.Actions.Search. Additionally, you can add other search engines
|
||||
-- such as those listed below.
|
||||
archwiki, ebay, news, reddit, urban :: S.SearchEngine
|
||||
|
||||
archwiki = S.searchEngine "archwiki" "https://wiki.archlinux.org/index.php?search="
|
||||
ebay = S.searchEngine "ebay" "https://www.ebay.com/sch/i.html?_nkw="
|
||||
news = S.searchEngine "news" "https://news.google.com/search?q="
|
||||
reddit = S.searchEngine "reddit" "https://www.reddit.com/search/?q="
|
||||
urban = S.searchEngine "urban" "https://www.urbandictionary.com/define.php?term="
|
||||
|
||||
-- This is the list of search engines that I want to use. Some are from
|
||||
-- XMonad.Actions.Search, and some are the ones that I added above.
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("a", archwiki)
|
||||
, ("d", S.duckduckgo)
|
||||
, ("e", ebay)
|
||||
, ("g", S.google)
|
||||
, ("h", S.hoogle)
|
||||
, ("i", S.images)
|
||||
, ("n", news)
|
||||
, ("r", reddit)
|
||||
, ("s", S.stackage)
|
||||
, ("t", S.thesaurus)
|
||||
, ("v", S.vocabulary)
|
||||
, ("b", S.wayback)
|
||||
, ("u", urban)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("z", S.amazon)
|
||||
]
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- WORKSPACES
|
||||
------------------------------------------------------------------------
|
||||
-- TreeSelect workspaces
|
||||
myWorkspaces :: Forest String
|
||||
myWorkspaces = [ Node "dev"
|
||||
[ Node "terminal" []
|
||||
, Node "emacs" []
|
||||
, Node "docs" []
|
||||
, Node "files" []
|
||||
, Node "programming"
|
||||
[ Node "haskell" []
|
||||
, Node "python" []
|
||||
, Node "shell" []
|
||||
]
|
||||
, Node "virtualization" []
|
||||
]
|
||||
, Node "web"
|
||||
[ Node "browser" []
|
||||
, Node "chat" []
|
||||
, Node "email" []
|
||||
, Node "rss" []
|
||||
, Node "web conference" []
|
||||
]
|
||||
, Node "graphics"
|
||||
[ Node "gimp" []
|
||||
, Node "image viewer" []
|
||||
]
|
||||
, Node "music"
|
||||
[ Node "audio editor" []
|
||||
, Node "music player" []
|
||||
]
|
||||
, Node "video"
|
||||
[ Node "obs" []
|
||||
, Node "kdenlive" []
|
||||
, Node "video player" []
|
||||
]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MANAGEHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets some rules for certain programs. Examples include forcing certain
|
||||
-- programs to always float, or to always appear on a certain workspace.
|
||||
-- Forcing programs to a certain workspace with a doShift requires xdotool
|
||||
-- if you are using clickable workspaces. You need the className or title
|
||||
-- of the program. Use xprop to get this info.
|
||||
|
||||
myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
|
||||
myManageHook = composeAll
|
||||
-- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
|
||||
-- I'm doing it this way because otherwise I would have to write out
|
||||
-- the full name of my clickable workspaces, which would look like:
|
||||
-- doShift "<action xdotool super+8>gfx</action>"
|
||||
[ className =? "obs" --> doShift ( "video.obs" )
|
||||
, title =? "firefox" --> doShift ( "web.browser" )
|
||||
, title =? "qutebrowser" --> doShift ( "web.browser" )
|
||||
, className =? "mpv" --> doShift ( "video.movie player" )
|
||||
, className =? "vlc" --> doShift ( "video.movie player" )
|
||||
, className =? "Gimp" --> doShift ( "graphics.gimp")
|
||||
, className =? "Gimp" --> doFloat
|
||||
, title =? "Oracle VM VirtualBox Manager" --> doFloat
|
||||
, className =? "VirtualBox Manager" --> doShift ( "dev.virtualization" )
|
||||
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
|
||||
] <+> namedScratchpadManageHook myScratchPads
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LOGHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Override the PP values as you would otherwise, adding colors etc depending
|
||||
-- on the statusbar used
|
||||
myLogHook :: D.Client -> PP
|
||||
myLogHook dbus = def
|
||||
{ ppOutput = dbusOutput dbus
|
||||
, ppCurrent = wrap ("%{F" ++ color4 ++ "} ") "%{F-}"
|
||||
, ppVisible = wrap ("%{F" ++ color1 ++ "} ") "%{F-}"
|
||||
, ppUrgent = wrap ("%{F" ++ color3 ++ "} ") "%{F-}"
|
||||
, ppHidden = wrap ("%{F" ++ color1 ++ "} ") "%{F-}"
|
||||
, ppTitle = wrap ("%{F" ++ color2 ++ "}")"%{F-}"
|
||||
, ppSep = " | "
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LAYOUTS
|
||||
------------------------------------------------------------------------
|
||||
-- Makes setting the spacingRaw simpler to write. The spacingRaw
|
||||
-- module adds a configurable amount of space around windows.
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
|
||||
|
||||
-- Below is a variation of the above except no borders are applied
|
||||
-- if fewer than two windows. So a single window has no gaps.
|
||||
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
|
||||
|
||||
-- Defining a bunch of layouts, many that I don't use.
|
||||
tall = renamed [Replace "tall"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
magnify = renamed [Replace "magnify"]
|
||||
$ magnifier
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
monocle = renamed [Replace "monocle"]
|
||||
$ limitWindows 20 Full
|
||||
floats = renamed [Replace "floats"]
|
||||
$ limitWindows 20 simplestFloat
|
||||
grid = renamed [Replace "grid"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ mkToggle (single MIRROR)
|
||||
$ Grid (16/10)
|
||||
spirals = renamed [Replace "spirals"]
|
||||
$ mySpacing' 8
|
||||
$ spiral (6/7)
|
||||
threeCol = renamed [Replace "threeCol"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
threeRow = renamed [Replace "threeRow"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
-- Mirror takes a layout and rotates it by 90 degrees.
|
||||
-- So we are applying Mirror to the ThreeCol layout.
|
||||
$ Mirror
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
tabs = renamed [Replace "tabs"]
|
||||
-- I cannot add spacing to this layout because it will
|
||||
-- add spacing between window and tabs which looks bad.
|
||||
$ tabbed shrinkText myTabConfig
|
||||
where
|
||||
myTabConfig = def { fontName = "xft:Mononoki Nerd Font:regular:pixelsize=11"
|
||||
, activeColor = "#292d3e"
|
||||
, inactiveColor = "#3e445e"
|
||||
, activeBorderColor = "#292d3e"
|
||||
, inactiveBorderColor = "#292d3e"
|
||||
, activeTextColor = "#ffffff"
|
||||
, inactiveTextColor = "#d0d0d0"
|
||||
}
|
||||
|
||||
-- Theme for showWName which prints current workspace when you change workspaces.
|
||||
myShowWNameTheme :: SWNConfig
|
||||
myShowWNameTheme = def
|
||||
{ swn_font = "xft:Sans:bold:size=60"
|
||||
, swn_fade = 1.0
|
||||
, swn_bgcolor = "#000000"
|
||||
, swn_color = "#FFFFFF"
|
||||
}
|
||||
|
||||
-- The layout hook
|
||||
myLayoutHook = avoidStruts $ mouseResize $ windowArrange $ T.toggleLayouts floats $
|
||||
mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
|
||||
where
|
||||
-- I've commented out the layouts I don't use.
|
||||
myDefaultLayout = tall
|
||||
||| magnify
|
||||
||| noBorders monocle
|
||||
||| floats
|
||||
-- ||| grid
|
||||
||| noBorders tabs
|
||||
-- ||| spirals
|
||||
-- ||| threeCol
|
||||
-- ||| threeRow
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SCRATCHPADS
|
||||
------------------------------------------------------------------------
|
||||
-- Allows to have several floating scratchpads running different applications.
|
||||
-- Import Util.NamedScratchpad. Bind a key to namedScratchpadSpawnAction.
|
||||
myScratchPads :: [NamedScratchpad]
|
||||
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
|
||||
, NS "mocp" spawnMocp findMocp manageMocp
|
||||
]
|
||||
where
|
||||
spawnTerm = myTerminal ++ " -n scratchpad"
|
||||
findTerm = resource =? "scratchpad"
|
||||
manageTerm = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
spawnMocp = myTerminal ++ " -n mocp 'mocp'"
|
||||
findMocp = resource =? "mocp"
|
||||
manageMocp = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- KEYBINDINGS
|
||||
------------------------------------------------------------------------
|
||||
-- I am using the Xmonad.Util.EZConfig module which allows keybindings
|
||||
-- to be written in simpler, emacs-like format.
|
||||
myKeys :: [(String, X ())]
|
||||
myKeys =
|
||||
-- Xmonad
|
||||
[ ("M-C-r", spawn "xmonad --recompile") -- Recompiles xmonad
|
||||
, ("M-S-r", spawn "xmonad --restart") -- Restarts xmonad
|
||||
, ("M-S-q", io exitSuccess) -- Quits xmonad
|
||||
|
||||
-- Open my preferred terminal
|
||||
, ("M-<Return>", spawn myTerminal)
|
||||
|
||||
-- Run Prompt
|
||||
, ("M-S-<Return>", shellPrompt dtXPConfig) -- Shell Prompt
|
||||
|
||||
-- Windows
|
||||
, ("M-S-c", kill1) -- Kill the currently focused client
|
||||
, ("M-S-a", killAll) -- Kill all windows on current workspace
|
||||
|
||||
-- Floating windows
|
||||
, ("M-f", sendMessage (T.Toggle "floats")) -- Toggles my 'floats' layout
|
||||
, ("M-<Delete>", withFocused $ windows . W.sink) -- Push floating window back to tile
|
||||
, ("M-S-<Delete>", sinkAll) -- Push ALL floating windows to tile
|
||||
|
||||
-- Grid Select (CTRL-g followed by a key)
|
||||
, ("C-g g", spawnSelected' myAppGrid) -- grid select favorite apps
|
||||
, ("C-g m", spawnSelected' myBookmarkGrid) -- grid select some bookmarks
|
||||
, ("C-g c", spawnSelected' myConfigGrid) -- grid select useful config files
|
||||
, ("C-g t", goToSelected $ mygridConfig myColorizer) -- goto selected window
|
||||
, ("C-g b", bringSelected $ mygridConfig myColorizer) -- bring selected window
|
||||
|
||||
-- Tree Select/
|
||||
-- tree select actions menu
|
||||
, ("C-t a", treeselectAction tsDefaultConfig)
|
||||
-- tree select workspaces menu
|
||||
, ("C-t t", TS.treeselectWorkspace tsDefaultConfig myWorkspaces W.greedyView)
|
||||
-- tree select choose workspace to send window
|
||||
, ("C-t g", TS.treeselectWorkspace tsDefaultConfig myWorkspaces W.shift)
|
||||
|
||||
-- Windows navigation
|
||||
, ("M-m", windows W.focusMaster) -- Move focus to the master window
|
||||
, ("M-j", windows W.focusDown) -- Move focus to the next window
|
||||
, ("M-k", windows W.focusUp) -- Move focus to the prev window
|
||||
--, ("M-S-m", windows W.swapMaster) -- Swap the focused window and the master window
|
||||
, ("M-S-j", windows W.swapDown) -- Swap focused window with next window
|
||||
, ("M-S-k", windows W.swapUp) -- Swap focused window with prev window
|
||||
, ("M-<Backspace>", promote) -- Moves focused window to master, others maintain order
|
||||
, ("M1-S-<Tab>", rotSlavesDown) -- Rotate all windows except master and keep focus in place
|
||||
, ("M1-C-<Tab>", rotAllDown) -- Rotate all the windows in the current stack
|
||||
--, ("M-S-s", windows copyToAll)
|
||||
, ("M-C-s", killAllOtherCopies)
|
||||
|
||||
-- Layouts
|
||||
, ("M-<Tab>", sendMessage NextLayout) -- Switch to next layout
|
||||
, ("M-C-M1-<Up>", sendMessage Arrange)
|
||||
, ("M-C-M1-<Down>", sendMessage DeArrange)
|
||||
, ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full
|
||||
, ("M-S-<Space>", sendMessage ToggleStruts) -- Toggles struts
|
||||
, ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder
|
||||
, ("M-<KP_Multiply>", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane
|
||||
, ("M-<KP_Divide>", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane
|
||||
, ("M-S-<KP_Multiply>", increaseLimit) -- Increase number of windows
|
||||
, ("M-S-<KP_Divide>", decreaseLimit) -- Decrease number of windows
|
||||
|
||||
, ("M-h", sendMessage Shrink) -- Shrink horiz window width
|
||||
, ("M-l", sendMessage Expand) -- Expand horiz window width
|
||||
, ("M-C-j", sendMessage MirrorShrink) -- Shrink vert window width
|
||||
, ("M-C-k", sendMessage MirrorExpand) -- Exoand vert window width
|
||||
|
||||
-- Workspaces
|
||||
, ("M-.", nextScreen) -- Switch focus to next monitor
|
||||
, ("M-,", prevScreen) -- Switch focus to prev monitor
|
||||
, ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws
|
||||
, ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws
|
||||
|
||||
-- Scratchpads
|
||||
, ("M-C-<Return>", namedScratchpadAction myScratchPads "terminal")
|
||||
, ("M-C-c", namedScratchpadAction myScratchPads "mocp")
|
||||
|
||||
-- Controls for mocp music player.
|
||||
, ("M-u p", spawn "mocp --play")
|
||||
, ("M-u l", spawn "mocp --next")
|
||||
, ("M-u h", spawn "mocp --previous")
|
||||
, ("M-u <Space>", spawn "mocp --toggle-pause")
|
||||
|
||||
-- Emacs (CTRL-e followed by a key)
|
||||
, ("C-e e", spawn "emacsclient -c -a ''") -- start emacs
|
||||
, ("C-e b", spawn "emacsclient -c -a '' --eval '(ibuffer)'") -- list emacs buffers
|
||||
, ("C-e d", spawn "emacsclient -c -a '' --eval '(dired nil)'") -- dired emacs file manager
|
||||
, ("C-e m", spawn "emacsclient -c -a '' --eval '(mu4e)'") -- mu4e emacs email client
|
||||
, ("C-e n", spawn "emacsclient -c -a '' --eval '(elfeed)'") -- elfeed emacs rss client
|
||||
, ("C-e s", spawn "emacsclient -c -a '' --eval '(eshell)'") -- eshell within emacs
|
||||
, ("C-e t", spawn "emacsclient -c -a '' --eval '(+vterm/here nil)'") -- eshell within emacs
|
||||
-- emms is an emacs audio player. I set it to auto start playing in a specific directory.
|
||||
, ("C-e a", spawn "emacsclient -c -a '' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")
|
||||
|
||||
--- My Applications (Super+Alt+Key)
|
||||
, ("M-M1-a", spawn (myTerminal ++ " -e ncpamixer"))
|
||||
, ("M-M1-b", spawn "surf www.youtube.com/c/DistroTube/")
|
||||
, ("M-M1-e", spawn (myTerminal ++ " -e neomutt"))
|
||||
, ("M-M1-f", spawn (myTerminal ++ " -e sh ./.config/vifm/scripts/vifmrun"))
|
||||
, ("M-M1-i", spawn (myTerminal ++ " -e irssi"))
|
||||
, ("M-M1-j", spawn (myTerminal ++ " -e joplin"))
|
||||
, ("M-M1-l", spawn (myTerminal ++ " -e lynx -cfg=~/.lynx/lynx.cfg -lss=~/.lynx/lynx.lss gopher://distro.tube"))
|
||||
, ("M-M1-m", spawn (myTerminal ++ " -e mocp"))
|
||||
, ("M-M1-n", spawn (myTerminal ++ " -e newsboat"))
|
||||
, ("M-M1-p", spawn (myTerminal ++ " -e pianobar"))
|
||||
, ("M-M1-r", spawn (myTerminal ++ " -e rtv"))
|
||||
, ("M-M1-t", spawn (myTerminal ++ " -e toot curses"))
|
||||
, ("M-M1-w", spawn (myTerminal ++ " -e wopr report.xml"))
|
||||
, ("M-M1-y", spawn (myTerminal ++ " -e youtube-viewer"))
|
||||
|
||||
-- Multimedia Keys
|
||||
, ("<XF86AudioPlay>", spawn "cmus toggle")
|
||||
, ("<XF86AudioPrev>", spawn "cmus prev")
|
||||
, ("<XF86AudioNext>", spawn "cmus next")
|
||||
-- , ("<XF86AudioMute>", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04.
|
||||
, ("<XF86AudioLowerVolume>", spawn "amixer set Master 5%- unmute")
|
||||
, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 5%+ unmute")
|
||||
, ("<XF86HomePage>", spawn "firefox")
|
||||
, ("<XF86Search>", safeSpawn "firefox" ["https://www.google.com/"])
|
||||
, ("<XF86Mail>", runOrRaise "geary" (resource =? "thunderbird"))
|
||||
, ("<XF86Calculator>", runOrRaise "gcalctool" (resource =? "gcalctool"))
|
||||
, ("<XF86Eject>", spawn "toggleeject")
|
||||
, ("<Print>", spawn "scrotd 0")
|
||||
]
|
||||
-- Appending search engine prompts to keybindings list.
|
||||
-- Look at "search engines" section of this config for values for "k".
|
||||
++ [("M-s " ++ k, S.promptSearch dtXPConfig' f) | (k,f) <- searchList ]
|
||||
++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
-- Appending some extra xprompts to keybindings list.
|
||||
-- Look at "xprompt settings" section this of config for values for "k".
|
||||
++ [("M-p " ++ k, f dtXPConfig') | (k,f) <- promptList ]
|
||||
++ [("M-p " ++ k, f dtXPConfig' g) | (k,f,g) <- promptList' ]
|
||||
-- The following lines are needed for named scratchpads.
|
||||
where nonNSP = WSIs (return (\ws -> W.tag ws /= "nsp"))
|
||||
nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "nsp"))
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MAIN
|
||||
------------------------------------------------------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
dbus <- D.connectSession
|
||||
-- Request access to the DBus name
|
||||
D.requestName dbus (D.busName_ "org.xmonad.Log")
|
||||
[D.nameAllowReplacement, D.nameReplaceExisting, D.nameDoNotQueue]
|
||||
-- The xmonad, ya know...what the window manager is named after.
|
||||
xmonad $ ewmh $ docks $ defaults { logHook = dynamicLogWithPP (myLogHook dbus) }
|
||||
|
||||
-- Emit a DBus signal on log updates
|
||||
dbusOutput :: D.Client -> String -> IO ()
|
||||
dbusOutput dbus str = do
|
||||
let signal = (D.signal objectPath interfaceName memberName) {
|
||||
D.signalBody = [D.toVariant $ UTF8.decodeString str]
|
||||
}
|
||||
D.emit dbus signal
|
||||
where
|
||||
objectPath = D.objectPath_ "/org/xmonad/Log"
|
||||
interfaceName = D.interfaceName_ "org.xmonad.Log"
|
||||
memberName = D.memberName_ "Update"
|
||||
|
||||
defaults = def
|
||||
{ handleEventHook = serverModeEventHookCmd
|
||||
<+> serverModeEventHook
|
||||
<+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
|
||||
<+> docksEventHook
|
||||
, modMask = myModMask
|
||||
, terminal = myTerminal
|
||||
, workspaces = TS.toWorkspaces myWorkspaces
|
||||
, layoutHook = showWName' myShowWNameTheme $ smartBorders $ myLayoutHook
|
||||
, normalBorderColor = myNormColor
|
||||
, focusedBorderColor = myFocusColor
|
||||
, manageHook = myManageHook <+> manageHook def
|
||||
, borderWidth = myBorderWidth
|
||||
, startupHook = myStartupHook
|
||||
} `additionalKeysP` myKeys
|
||||
@@ -0,0 +1,795 @@
|
||||
-- Xmonad is a dynamically tiling X11 window manager that is written and
|
||||
-- configured in Haskell. Official documentation: https://xmonad.org
|
||||
|
||||
-- This is the xmonad configuration of Derek Taylor (DistroTube)
|
||||
-- My YouTube: http://www.youtube.com/c/DistroTube
|
||||
-- My GitLab: http://www.gitlab.com/dwt1/
|
||||
|
||||
-- This config is massively long. It is purposely bloated with a ton of
|
||||
-- examples of what you can do with xmonad. It is written more as a
|
||||
-- study guide rather than a config that you should download and use.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- IMPORTS
|
||||
------------------------------------------------------------------------
|
||||
-- Base
|
||||
import XMonad
|
||||
import System.IO (hPutStrLn)
|
||||
import System.Exit (exitSuccess)
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
-- Actions
|
||||
import XMonad.Actions.CopyWindow (kill1, killAllOtherCopies)
|
||||
import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Actions.MouseResize
|
||||
import XMonad.Actions.Promote
|
||||
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
|
||||
import qualified XMonad.Actions.TreeSelect as TS
|
||||
import XMonad.Actions.WindowGo (runOrRaise)
|
||||
import XMonad.Actions.WithAll (sinkAll, killAll)
|
||||
import qualified XMonad.Actions.Search as S
|
||||
|
||||
-- Data
|
||||
import Data.Char (isSpace)
|
||||
import Data.Monoid
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Tree
|
||||
import qualified Data.Tuple.Extra as TE
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- Hooks
|
||||
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
|
||||
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
|
||||
import XMonad.Hooks.FadeInactive
|
||||
import XMonad.Hooks.ManageDocks (avoidStruts, docksEventHook, manageDocks, ToggleStruts(..))
|
||||
import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat)
|
||||
import XMonad.Hooks.ServerMode
|
||||
import XMonad.Hooks.SetWMName
|
||||
import XMonad.Hooks.WorkspaceHistory
|
||||
|
||||
-- Layouts
|
||||
import XMonad.Layout.GridVariants (Grid(Grid))
|
||||
import XMonad.Layout.SimplestFloat
|
||||
import XMonad.Layout.Spiral
|
||||
import XMonad.Layout.ResizableTile
|
||||
import XMonad.Layout.Tabbed
|
||||
import XMonad.Layout.ThreeColumns
|
||||
|
||||
-- Layouts modifiers
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
|
||||
import XMonad.Layout.Magnifier
|
||||
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
|
||||
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.Renamed (renamed, Rename(Replace))
|
||||
import XMonad.Layout.ShowWName
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
|
||||
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
|
||||
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
|
||||
|
||||
-- Prompt
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.Input
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Man
|
||||
import XMonad.Prompt.Pass
|
||||
import XMonad.Prompt.Shell (shellPrompt)
|
||||
import XMonad.Prompt.Ssh
|
||||
import XMonad.Prompt.XMonad
|
||||
import Control.Arrow (first)
|
||||
|
||||
-- Utilities
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
|
||||
import XMonad.Util.SpawnOnce
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- VARIABLES
|
||||
------------------------------------------------------------------------
|
||||
-- It's nice to assign values to stuff that you will use more than once
|
||||
-- in the config. Setting values for things like font, terminal and editor
|
||||
-- means you only have to change the value here to make changes globally.
|
||||
myFont :: String
|
||||
myFont = "xft:Mononoki Nerd Font:bold:size=9"
|
||||
|
||||
myModMask :: KeyMask
|
||||
myModMask = mod4Mask -- Sets modkey to super/windows key
|
||||
|
||||
myTerminal :: String
|
||||
myTerminal = "alacritty" -- Sets default terminal
|
||||
|
||||
myBrowser :: String
|
||||
myBrowser = myTerminal ++ " -e lynx " -- Sets lynx as browser for tree select
|
||||
-- myBrowser = "firefox " -- Sets firefox as browser for tree select
|
||||
|
||||
myEditor :: String
|
||||
myEditor = "emacsclient -c -a emacs " -- Sets emacs as editor for tree select
|
||||
-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor for tree select
|
||||
|
||||
myBorderWidth :: Dimension
|
||||
myBorderWidth = 2 -- Sets border width for windows
|
||||
|
||||
myNormColor :: String
|
||||
myNormColor = "#292d3e" -- Border color of normal windows
|
||||
|
||||
myFocusColor :: String
|
||||
myFocusColor = "#bbc5ff" -- Border color of focused windows
|
||||
|
||||
altMask :: KeyMask
|
||||
altMask = mod1Mask -- Setting this for use in xprompts
|
||||
|
||||
windowCount :: X (Maybe String)
|
||||
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- AUTOSTART
|
||||
------------------------------------------------------------------------
|
||||
myStartupHook :: X ()
|
||||
myStartupHook = do
|
||||
spawnOnce "nitrogen --restore &"
|
||||
spawnOnce "picom &"
|
||||
spawnOnce "nm-applet &"
|
||||
spawnOnce "volumeicon &"
|
||||
spawnOnce "trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 --tint 0x292d3e --height 18 &"
|
||||
spawnOnce "/usr/bin/emacs --daemon &"
|
||||
-- spawnOnce "kak -d -s mysession &"
|
||||
setWMName "LG3D"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- GRID SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- GridSelect displays items (programs, open windows, etc.) in a 2D grid
|
||||
-- and lets the user select from it with the cursor/hjkl keys or the mouse.
|
||||
myColorizer :: Window -> Bool -> X (String, String)
|
||||
myColorizer = colorRangeFromClassName
|
||||
(0x29,0x2d,0x3e) -- lowest inactive bg
|
||||
(0x29,0x2d,0x3e) -- highest inactive bg
|
||||
(0xc7,0x92,0xea) -- active bg
|
||||
(0xc0,0xa7,0x9a) -- inactive fg
|
||||
(0x29,0x2d,0x3e) -- active fg
|
||||
|
||||
-- gridSelect menu layout
|
||||
mygridConfig :: p -> GSConfig Window
|
||||
mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
spawnSelected' :: [(String, String)] -> X ()
|
||||
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
|
||||
where conf = def
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
-- The lists below are actually 3-tuples for use with gridSelect and treeSelect.
|
||||
-- TreeSelect uses all three values in the 3-tuples but GridSelect only needs first
|
||||
-- two values in each list (see myAppGrid, myBookmarkGrid and myConfigGrid below).
|
||||
myApplications :: [(String, String, String)]
|
||||
myApplications = [ ("Audacity", "audacity", "Graphical cross-platform audio eidtor")
|
||||
, ("Deadbeef", "deadbeef", "Lightweight GUI audio player")
|
||||
, ("Emacs", "emacs", "Much more than a text editor")
|
||||
, ("Firefox", "firefox", "The famous open source web browser")
|
||||
, ("Geany", "geany", "A nice text editor")
|
||||
, ("Geary", "geary", "Email client that is attractive")
|
||||
, ("Gimp", "gimp", "Open source alternative to Photoshop")
|
||||
, ("Kdenlive", "kdenlive", "A great open source video editor")
|
||||
, ("LibreOffice Impress", "loimpress", "For making presentations")
|
||||
, ("LibreOffice Writer", "lowriter", "A fully featured word processor")
|
||||
, ("OBS", "obs", "Open broadcaster software")
|
||||
, ("PCManFM", "pcmanfm", "Lightweight graphical file manager")
|
||||
, ("Simple Terminal", "st", "Suckless simple terminal")
|
||||
, ("Steam", "steam", "Proprietary gaming platform")
|
||||
, ("Surf Browser", "surf suckless.org", "Suckless surf web browser")
|
||||
, ("Xonotic", "xonotic-glx", "A fast-paced first person shooter")
|
||||
]
|
||||
|
||||
myBookmarks :: [(String, String, String)]
|
||||
myBookmarks = [ ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
]
|
||||
|
||||
myConfigs :: [(String, String, String)]
|
||||
myConfigs = [ ("bashrc", myEditor ++ "/home/dt/.bashrc", "the bourne again shell")
|
||||
, ("doom emacs config.el", myEditor ++ "/home/dt/.doom.d/config.el", "doom emacs config")
|
||||
, ("doom emacs init.el", myEditor ++ "/home/dt/.doom.d/init.el", "doom emacs init")
|
||||
, ("dwm", myEditor ++ "/home/dt/dwm-distrotube/config.h", "dwm config file")
|
||||
, ("qtile", myEditor ++ "/home/dt/.config/qtile/config.py", "qtile config")
|
||||
, ("xmonad.hs", myEditor ++ "/home/dt/.xmonad/xmonad.hs", "xmonad config")
|
||||
, ("zshrc", myEditor ++ "/home/dt/.zshrc", "config for the z shell")
|
||||
]
|
||||
|
||||
-- Let's take myApplications, myBookmarks and myConfigs and take only
|
||||
-- the first two values from those 3-tuples (for GridSelect).
|
||||
myAppGrid :: [(String, String)]
|
||||
myAppGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myApplications
|
||||
|
||||
myBookmarkGrid :: [(String, String)]
|
||||
myBookmarkGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myBookmarks
|
||||
|
||||
myConfigGrid :: [(String, String)]
|
||||
myConfigGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myConfigs
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- TREE SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- TreeSelect displays your workspaces or actions in a Tree-like format.
|
||||
-- You can select desired workspace/action with the cursor or hjkl keys.
|
||||
|
||||
treeselectAction :: TS.TSConfig (X ()) -> X ()
|
||||
treeselectAction a = TS.treeselectAction a
|
||||
[ Node (TS.TSNode "applications" "a list of programs I use often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myApplications !! n)
|
||||
(TE.thd3 $ myApplications !! n)
|
||||
(spawn $ TE.snd3 $ myApplications !! n)
|
||||
) [] | n <- [0..(length myApplications - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "bookmarks" "a list of web bookmarks" (return ()))
|
||||
[Node (TS.TSNode(TE.fst3 $ myBookmarks !! n)
|
||||
(TE.thd3 $ myBookmarks !! n)
|
||||
(spawn $ TE.snd3 $ myBookmarks !! n)
|
||||
) [] | n <- [0..(length myBookmarks - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "config files" "config files that edit often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myConfigs !! n)
|
||||
(TE.thd3 $ myConfigs !! n)
|
||||
(spawn $ TE.snd3 $ myConfigs !! n)
|
||||
) [] | n <- [0..(length myConfigs - 1)]
|
||||
]
|
||||
]
|
||||
|
||||
-- Configuration options for treeSelect
|
||||
tsDefaultConfig :: TS.TSConfig a
|
||||
tsDefaultConfig = TS.TSConfig { TS.ts_hidechildren = True
|
||||
, TS.ts_background = 0xdd292d3e
|
||||
, TS.ts_font = myFont
|
||||
, TS.ts_node = (0xffd0d0d0, 0xff202331)
|
||||
, TS.ts_nodealt = (0xffd0d0d0, 0xff292d3e)
|
||||
, TS.ts_highlight = (0xffffffff, 0xff755999)
|
||||
, TS.ts_extra = 0xffd0d0d0
|
||||
, TS.ts_node_width = 200
|
||||
, TS.ts_node_height = 20
|
||||
, TS.ts_originX = 0
|
||||
, TS.ts_originY = 0
|
||||
, TS.ts_indent = 80
|
||||
, TS.ts_navigate = myTreeNavigation
|
||||
}
|
||||
|
||||
-- Keybindings for treeSelect menus. Use h-j-k-l to navigate.
|
||||
-- Use 'o' and 'i' to move forward/back in the workspace history.
|
||||
-- Single KEY's are for top-level nodes. SUPER+KEY are for the
|
||||
-- second-level nodes. SUPER+ALT+KEY are third-level nodes.
|
||||
myTreeNavigation = M.fromList
|
||||
[ ((0, xK_Escape), TS.cancel)
|
||||
, ((0, xK_Return), TS.select)
|
||||
, ((0, xK_space), TS.select)
|
||||
, ((0, xK_Up), TS.movePrev)
|
||||
, ((0, xK_Down), TS.moveNext)
|
||||
, ((0, xK_Left), TS.moveParent)
|
||||
, ((0, xK_Right), TS.moveChild)
|
||||
, ((0, xK_k), TS.movePrev)
|
||||
, ((0, xK_j), TS.moveNext)
|
||||
, ((0, xK_h), TS.moveParent)
|
||||
, ((0, xK_l), TS.moveChild)
|
||||
, ((0, xK_o), TS.moveHistBack)
|
||||
, ((0, xK_i), TS.moveHistForward)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT SETTINGS
|
||||
------------------------------------------------------------------------
|
||||
dtXPConfig :: XPConfig
|
||||
dtXPConfig = def
|
||||
{ font = myFont
|
||||
, bgColor = "#292d3e"
|
||||
, fgColor = "#d0d0d0"
|
||||
, bgHLight = "#c792ea"
|
||||
, fgHLight = "#000000"
|
||||
, borderColor = "#535974"
|
||||
, promptBorderWidth = 0
|
||||
, promptKeymap = dtXPKeymap
|
||||
, position = Top
|
||||
-- , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.3 }
|
||||
, height = 20
|
||||
, historySize = 256
|
||||
, historyFilter = id
|
||||
, defaultText = []
|
||||
, autoComplete = Just 100000 -- set Just 100000 for .1 sec
|
||||
, showCompletionOnTab = False
|
||||
-- , searchPredicate = isPrefixOf
|
||||
, searchPredicate = fuzzyMatch
|
||||
, alwaysHighlight = True
|
||||
, maxComplRows = Nothing -- set to Just 5 for 5 rows
|
||||
}
|
||||
|
||||
-- The same config above minus the autocomplete feature which is annoying
|
||||
-- on certain Xprompts, like the search engine prompts.
|
||||
dtXPConfig' :: XPConfig
|
||||
dtXPConfig' = dtXPConfig
|
||||
{ autoComplete = Nothing
|
||||
}
|
||||
|
||||
-- A list of all of the standard Xmonad prompts and a key press assigned to them.
|
||||
-- These are used in conjunction with keybinding I set later in the config.
|
||||
promptList :: [(String, XPConfig -> X ())]
|
||||
promptList = [ ("m", manPrompt) -- manpages prompt
|
||||
, ("p", passPrompt) -- get passwords (requires 'pass')
|
||||
, ("g", passGeneratePrompt) -- generate passwords (requires 'pass')
|
||||
, ("r", passRemovePrompt) -- remove passwords (requires 'pass')
|
||||
, ("s", sshPrompt) -- ssh prompt
|
||||
, ("x", xmonadPrompt) -- xmonad prompt
|
||||
]
|
||||
|
||||
-- Same as the above list except this is for my custom prompts.
|
||||
promptList' :: [(String, XPConfig -> String -> X (), String)]
|
||||
promptList' = [ ("c", calcPrompt, "qalc") -- requires qalculate-gtk
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- CUSTOM PROMPTS
|
||||
------------------------------------------------------------------------
|
||||
-- calcPrompt requires a cli calculator called qalcualte-gtk.
|
||||
-- You could use this as a template for other custom prompts that
|
||||
-- use command line programs that return a single line of output.
|
||||
calcPrompt :: XPConfig -> String -> X ()
|
||||
calcPrompt c ans =
|
||||
inputPrompt c (trim ans) ?+ \input ->
|
||||
liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c
|
||||
where
|
||||
trim = f . f
|
||||
where f = reverse . dropWhile isSpace
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT KEYMAP (emacs-like key bindings for xprompts)
|
||||
------------------------------------------------------------------------
|
||||
dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ())
|
||||
dtXPKeymap = M.fromList $
|
||||
map (first $ (,) controlMask) -- control + <key>
|
||||
[ (xK_z, killBefore) -- kill line backwards
|
||||
, (xK_k, killAfter) -- kill line forwards
|
||||
, (xK_a, startOfLine) -- move to the beginning of the line
|
||||
, (xK_e, endOfLine) -- move to the end of the line
|
||||
, (xK_m, deleteString Next) -- delete a character foward
|
||||
, (xK_b, moveCursor Prev) -- move cursor forward
|
||||
, (xK_f, moveCursor Next) -- move cursor backward
|
||||
, (xK_BackSpace, killWord Prev) -- kill the previous word
|
||||
, (xK_y, pasteString) -- paste a string
|
||||
, (xK_g, quit) -- quit out of prompt
|
||||
, (xK_bracketleft, quit)
|
||||
]
|
||||
++
|
||||
map (first $ (,) altMask) -- meta key + <key>
|
||||
[ (xK_BackSpace, killWord Prev) -- kill the prev word
|
||||
, (xK_f, moveWord Next) -- move a word forward
|
||||
, (xK_b, moveWord Prev) -- move a word backward
|
||||
, (xK_d, killWord Next) -- kill the next word
|
||||
, (xK_n, moveHistory W.focusUp') -- move up thru history
|
||||
, (xK_p, moveHistory W.focusDown') -- move down thru history
|
||||
]
|
||||
++
|
||||
map (first $ (,) 0) -- <key>
|
||||
[ (xK_Return, setSuccess True >> setDone True)
|
||||
, (xK_KP_Enter, setSuccess True >> setDone True)
|
||||
, (xK_BackSpace, deleteString Prev)
|
||||
, (xK_Delete, deleteString Next)
|
||||
, (xK_Left, moveCursor Prev)
|
||||
, (xK_Right, moveCursor Next)
|
||||
, (xK_Home, startOfLine)
|
||||
, (xK_End, endOfLine)
|
||||
, (xK_Down, moveHistory W.focusUp')
|
||||
, (xK_Up, moveHistory W.focusDown')
|
||||
, (xK_Escape, quit)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SEARCH ENGINES
|
||||
------------------------------------------------------------------------
|
||||
-- Xmonad has several search engines available to use located in
|
||||
-- XMonad.Actions.Search. Additionally, you can add other search engines
|
||||
-- such as those listed below.
|
||||
archwiki, ebay, news, reddit, urban :: S.SearchEngine
|
||||
|
||||
archwiki = S.searchEngine "archwiki" "https://wiki.archlinux.org/index.php?search="
|
||||
ebay = S.searchEngine "ebay" "https://www.ebay.com/sch/i.html?_nkw="
|
||||
news = S.searchEngine "news" "https://news.google.com/search?q="
|
||||
reddit = S.searchEngine "reddit" "https://www.reddit.com/search/?q="
|
||||
urban = S.searchEngine "urban" "https://www.urbandictionary.com/define.php?term="
|
||||
|
||||
-- This is the list of search engines that I want to use. Some are from
|
||||
-- XMonad.Actions.Search, and some are the ones that I added above.
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("a", archwiki)
|
||||
, ("d", S.duckduckgo)
|
||||
, ("e", ebay)
|
||||
, ("g", S.google)
|
||||
, ("h", S.hoogle)
|
||||
, ("i", S.images)
|
||||
, ("n", news)
|
||||
, ("r", reddit)
|
||||
, ("s", S.stackage)
|
||||
, ("t", S.thesaurus)
|
||||
, ("v", S.vocabulary)
|
||||
, ("b", S.wayback)
|
||||
, ("u", urban)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("z", S.amazon)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- WORKSPACES
|
||||
------------------------------------------------------------------------
|
||||
-- My workspaces are clickable meaning that the mouse can be used to switch
|
||||
-- workspaces. This requires xdotool. You need to use UnsafeStdInReader instead
|
||||
-- of simply StdInReader in xmobar config so you can pass actions to it.
|
||||
|
||||
xmobarEscape :: String -> String
|
||||
xmobarEscape = concatMap doubleLts
|
||||
where
|
||||
doubleLts '<' = "<<"
|
||||
doubleLts x = [x]
|
||||
|
||||
myWorkspaces :: [String]
|
||||
myWorkspaces = clickable . map xmobarEscape
|
||||
$ ["dev", "www", "sys", "doc", "vbox", "chat", "mus", "vid", "gfx"]
|
||||
where
|
||||
clickable l = [ "<action=xdotool key super+" ++ show n ++ ">" ++ ws ++ "</action>" |
|
||||
(i,ws) <- zip [1..9] l,
|
||||
let n = i ]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MANAGEHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets some rules for certain programs. Examples include forcing certain
|
||||
-- programs to always float, or to always appear on a certain workspace.
|
||||
-- Forcing programs to a certain workspace with a doShift requires xdotool
|
||||
-- if you are using clickable workspaces. You need the className or title
|
||||
-- of the program. Use xprop to get this info.
|
||||
|
||||
myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
|
||||
myManageHook = composeAll
|
||||
-- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
|
||||
-- I'm doing it this way because otherwise I would have to write out
|
||||
-- the full name of my clickable workspaces, which would look like:
|
||||
-- doShift "<action xdotool super+8>gfx</action>"
|
||||
[ className =? "obs" --> doShift ( "video.obs" )
|
||||
, title =? "firefox" --> doShift ( "web.browser" )
|
||||
, title =? "qutebrowser" --> doShift ( "web.browser" )
|
||||
, className =? "mpv" --> doShift ( "video.movie player" )
|
||||
, className =? "vlc" --> doShift ( "video.movie player" )
|
||||
, className =? "Gimp" --> doShift ( "graphics.gimp")
|
||||
, className =? "Gimp" --> doFloat
|
||||
, title =? "Oracle VM VirtualBox Manager" --> doFloat
|
||||
, className =? "VirtualBox Manager" --> doShift ( "dev.virtualization" )
|
||||
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
|
||||
] <+> namedScratchpadManageHook myScratchPads
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LOGHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets opacity for inactive (unfocused) windows. I prefer to not use
|
||||
-- this feature so I've set opacity to 1.0. If you want opacity, set
|
||||
-- this to a value of less than 1 (such as 0.9 for 90% opacity).
|
||||
myLogHook :: X ()
|
||||
myLogHook = fadeInactiveLogHook fadeAmount
|
||||
where fadeAmount = 1.0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LAYOUTS
|
||||
------------------------------------------------------------------------
|
||||
-- Makes setting the spacingRaw simpler to write. The spacingRaw
|
||||
-- module adds a configurable amount of space around windows.
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
|
||||
|
||||
-- Below is a variation of the above except no borders are applied
|
||||
-- if fewer than two windows. So a single window has no gaps.
|
||||
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
|
||||
|
||||
-- Defining a bunch of layouts, many that I don't use.
|
||||
tall = renamed [Replace "tall"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
magnify = renamed [Replace "magnify"]
|
||||
$ magnifier
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
monocle = renamed [Replace "monocle"]
|
||||
$ limitWindows 20 Full
|
||||
floats = renamed [Replace "floats"]
|
||||
$ limitWindows 20 simplestFloat
|
||||
grid = renamed [Replace "grid"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ mkToggle (single MIRROR)
|
||||
$ Grid (16/10)
|
||||
spirals = renamed [Replace "spirals"]
|
||||
$ mySpacing' 8
|
||||
$ spiral (6/7)
|
||||
threeCol = renamed [Replace "threeCol"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
threeRow = renamed [Replace "threeRow"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
-- Mirror takes a layout and rotates it by 90 degrees.
|
||||
-- So we are applying Mirror to the ThreeCol layout.
|
||||
$ Mirror
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
tabs = renamed [Replace "tabs"]
|
||||
-- I cannot add spacing to this layout because it will
|
||||
-- add spacing between window and tabs which looks bad.
|
||||
$ tabbed shrinkText myTabConfig
|
||||
where
|
||||
myTabConfig = def { fontName = "xft:Mononoki Nerd Font:regular:pixelsize=11"
|
||||
, activeColor = "#292d3e"
|
||||
, inactiveColor = "#3e445e"
|
||||
, activeBorderColor = "#292d3e"
|
||||
, inactiveBorderColor = "#292d3e"
|
||||
, activeTextColor = "#ffffff"
|
||||
, inactiveTextColor = "#d0d0d0"
|
||||
}
|
||||
|
||||
-- Theme for showWName which prints current workspace when you change workspaces.
|
||||
myShowWNameTheme :: SWNConfig
|
||||
myShowWNameTheme = def
|
||||
{ swn_font = "xft:Sans:bold:size=60"
|
||||
, swn_fade = 1.0
|
||||
, swn_bgcolor = "#000000"
|
||||
, swn_color = "#FFFFFF"
|
||||
}
|
||||
|
||||
-- The layout hook
|
||||
myLayoutHook = avoidStruts $ mouseResize $ windowArrange $ T.toggleLayouts floats $
|
||||
mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
|
||||
where
|
||||
-- I've commented out the layouts I don't use.
|
||||
myDefaultLayout = tall
|
||||
||| magnify
|
||||
||| noBorders monocle
|
||||
||| floats
|
||||
-- ||| grid
|
||||
||| noBorders tabs
|
||||
-- ||| spirals
|
||||
-- ||| threeCol
|
||||
-- ||| threeRow
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SCRATCHPADS
|
||||
------------------------------------------------------------------------
|
||||
-- Allows to have several floating scratchpads running different applications.
|
||||
-- Import Util.NamedScratchpad. Bind a key to namedScratchpadSpawnAction.
|
||||
myScratchPads :: [NamedScratchpad]
|
||||
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
|
||||
, NS "mocp" spawnMocp findMocp manageMocp
|
||||
]
|
||||
where
|
||||
spawnTerm = myTerminal ++ " -n scratchpad"
|
||||
findTerm = resource =? "scratchpad"
|
||||
manageTerm = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
spawnMocp = myTerminal ++ " -n mocp 'mocp'"
|
||||
findMocp = resource =? "mocp"
|
||||
manageMocp = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- KEYBINDINGS
|
||||
------------------------------------------------------------------------
|
||||
-- I am using the Xmonad.Util.EZConfig module which allows keybindings
|
||||
-- to be written in simpler, emacs-like format.
|
||||
myKeys :: [(String, X ())]
|
||||
myKeys =
|
||||
-- Xmonad
|
||||
[ ("M-C-r", spawn "xmonad --recompile") -- Recompiles xmonad
|
||||
, ("M-S-r", spawn "xmonad --restart") -- Restarts xmonad
|
||||
, ("M-S-q", io exitSuccess) -- Quits xmonad
|
||||
|
||||
-- Open my preferred terminal
|
||||
, ("M-<Return>", spawn myTerminal)
|
||||
|
||||
-- Run Prompt
|
||||
, ("M-S-<Return>", shellPrompt dtXPConfig) -- Shell Prompt
|
||||
|
||||
-- Windows
|
||||
, ("M-S-c", kill1) -- Kill the currently focused client
|
||||
, ("M-S-a", killAll) -- Kill all windows on current workspace
|
||||
|
||||
-- Floating windows
|
||||
, ("M-f", sendMessage (T.Toggle "floats")) -- Toggles my 'floats' layout
|
||||
, ("M-<Delete>", withFocused $ windows . W.sink) -- Push floating window back to tile
|
||||
, ("M-S-<Delete>", sinkAll) -- Push ALL floating windows to tile
|
||||
|
||||
-- Grid Select (CTRL-g followed by a key)
|
||||
, ("C-g g", spawnSelected' myAppGrid) -- grid select favorite apps
|
||||
, ("C-g m", spawnSelected' myBookmarkGrid) -- grid select some bookmarks
|
||||
, ("C-g c", spawnSelected' myConfigGrid) -- grid select useful config files
|
||||
, ("C-g t", goToSelected $ mygridConfig myColorizer) -- goto selected window
|
||||
, ("C-g b", bringSelected $ mygridConfig myColorizer) -- bring selected window
|
||||
|
||||
-- Tree Select/
|
||||
-- tree select actions menu
|
||||
, ("C-t a", treeselectAction tsDefaultConfig)
|
||||
|
||||
-- Windows navigation
|
||||
, ("M-m", windows W.focusMaster) -- Move focus to the master window
|
||||
, ("M-j", windows W.focusDown) -- Move focus to the next window
|
||||
, ("M-k", windows W.focusUp) -- Move focus to the prev window
|
||||
--, ("M-S-m", windows W.swapMaster) -- Swap the focused window and the master window
|
||||
, ("M-S-j", windows W.swapDown) -- Swap focused window with next window
|
||||
, ("M-S-k", windows W.swapUp) -- Swap focused window with prev window
|
||||
, ("M-<Backspace>", promote) -- Moves focused window to master, others maintain order
|
||||
, ("M1-S-<Tab>", rotSlavesDown) -- Rotate all windows except master and keep focus in place
|
||||
, ("M1-C-<Tab>", rotAllDown) -- Rotate all the windows in the current stack
|
||||
--, ("M-S-s", windows copyToAll)
|
||||
, ("M-C-s", killAllOtherCopies)
|
||||
|
||||
-- Layouts
|
||||
, ("M-<Tab>", sendMessage NextLayout) -- Switch to next layout
|
||||
, ("M-C-M1-<Up>", sendMessage Arrange)
|
||||
, ("M-C-M1-<Down>", sendMessage DeArrange)
|
||||
, ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full
|
||||
, ("M-S-<Space>", sendMessage ToggleStruts) -- Toggles struts
|
||||
, ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder
|
||||
, ("M-<KP_Multiply>", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane
|
||||
, ("M-<KP_Divide>", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane
|
||||
, ("M-S-<KP_Multiply>", increaseLimit) -- Increase number of windows
|
||||
, ("M-S-<KP_Divide>", decreaseLimit) -- Decrease number of windows
|
||||
|
||||
, ("M-h", sendMessage Shrink) -- Shrink horiz window width
|
||||
, ("M-l", sendMessage Expand) -- Expand horiz window width
|
||||
, ("M-C-j", sendMessage MirrorShrink) -- Shrink vert window width
|
||||
, ("M-C-k", sendMessage MirrorExpand) -- Exoand vert window width
|
||||
|
||||
-- Workspaces
|
||||
, ("M-.", nextScreen) -- Switch focus to next monitor
|
||||
, ("M-,", prevScreen) -- Switch focus to prev monitor
|
||||
, ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws
|
||||
, ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws
|
||||
|
||||
-- Scratchpads
|
||||
, ("M-C-<Return>", namedScratchpadAction myScratchPads "terminal")
|
||||
, ("M-C-c", namedScratchpadAction myScratchPads "mocp")
|
||||
|
||||
-- Controls for mocp music player.
|
||||
, ("M-u p", spawn "mocp --play")
|
||||
, ("M-u l", spawn "mocp --next")
|
||||
, ("M-u h", spawn "mocp --previous")
|
||||
, ("M-u <Space>", spawn "mocp --toggle-pause")
|
||||
|
||||
-- Emacs (CTRL-e followed by a key)
|
||||
, ("C-e e", spawn "emacsclient -c -a ''") -- start emacs
|
||||
, ("C-e b", spawn "emacsclient -c -a '' --eval '(ibuffer)'") -- list emacs buffers
|
||||
, ("C-e d", spawn "emacsclient -c -a '' --eval '(dired nil)'") -- dired emacs file manager
|
||||
, ("C-e m", spawn "emacsclient -c -a '' --eval '(mu4e)'") -- mu4e emacs email client
|
||||
, ("C-e n", spawn "emacsclient -c -a '' --eval '(elfeed)'") -- elfeed emacs rss client
|
||||
, ("C-e s", spawn "emacsclient -c -a '' --eval '(eshell)'") -- eshell within emacs
|
||||
, ("C-e t", spawn "emacsclient -c -a '' --eval '(+vterm/here nil)'") -- eshell within emacs
|
||||
-- emms is an emacs audio player. I set it to auto start playing in a specific directory.
|
||||
, ("C-e a", spawn "emacsclient -c -a '' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")
|
||||
|
||||
--- My Applications (Super+Alt+Key)
|
||||
, ("M-M1-a", spawn (myTerminal ++ " -e ncpamixer"))
|
||||
, ("M-M1-b", spawn "surf www.youtube.com/c/DistroTube/")
|
||||
, ("M-M1-e", spawn (myTerminal ++ " -e neomutt"))
|
||||
, ("M-M1-f", spawn (myTerminal ++ " -e sh ./.config/vifm/scripts/vifmrun"))
|
||||
, ("M-M1-i", spawn (myTerminal ++ " -e irssi"))
|
||||
, ("M-M1-j", spawn (myTerminal ++ " -e joplin"))
|
||||
, ("M-M1-l", spawn (myTerminal ++ " -e lynx -cfg=~/.lynx/lynx.cfg -lss=~/.lynx/lynx.lss gopher://distro.tube"))
|
||||
, ("M-M1-m", spawn (myTerminal ++ " -e mocp"))
|
||||
, ("M-M1-n", spawn (myTerminal ++ " -e newsboat"))
|
||||
, ("M-M1-p", spawn (myTerminal ++ " -e pianobar"))
|
||||
, ("M-M1-r", spawn (myTerminal ++ " -e rtv"))
|
||||
, ("M-M1-t", spawn (myTerminal ++ " -e toot curses"))
|
||||
, ("M-M1-w", spawn (myTerminal ++ " -e wopr report.xml"))
|
||||
, ("M-M1-y", spawn (myTerminal ++ " -e youtube-viewer"))
|
||||
|
||||
-- Multimedia Keys
|
||||
, ("<XF86AudioPlay>", spawn "cmus toggle")
|
||||
, ("<XF86AudioPrev>", spawn "cmus prev")
|
||||
, ("<XF86AudioNext>", spawn "cmus next")
|
||||
-- , ("<XF86AudioMute>", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04.
|
||||
, ("<XF86AudioLowerVolume>", spawn "amixer set Master 5%- unmute")
|
||||
, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 5%+ unmute")
|
||||
, ("<XF86HomePage>", spawn "firefox")
|
||||
, ("<XF86Search>", safeSpawn "firefox" ["https://www.google.com/"])
|
||||
, ("<XF86Mail>", runOrRaise "geary" (resource =? "thunderbird"))
|
||||
, ("<XF86Calculator>", runOrRaise "gcalctool" (resource =? "gcalctool"))
|
||||
, ("<XF86Eject>", spawn "toggleeject")
|
||||
, ("<Print>", spawn "scrotd 0")
|
||||
]
|
||||
-- Appending search engine prompts to keybindings list.
|
||||
-- Look at "search engines" section of this config for values for "k".
|
||||
++ [("M-s " ++ k, S.promptSearch dtXPConfig' f) | (k,f) <- searchList ]
|
||||
++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
-- Appending some extra xprompts to keybindings list.
|
||||
-- Look at "xprompt settings" section this of config for values for "k".
|
||||
++ [("M-p " ++ k, f dtXPConfig') | (k,f) <- promptList ]
|
||||
++ [("M-p " ++ k, f dtXPConfig' g) | (k,f,g) <- promptList' ]
|
||||
-- The following lines are needed for named scratchpads.
|
||||
where nonNSP = WSIs (return (\ws -> W.tag ws /= "nsp"))
|
||||
nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "nsp"))
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MAIN
|
||||
------------------------------------------------------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Launching three instances of xmobar on their monitors.
|
||||
xmproc0 <- spawnPipe "xmobar -x 0 /home/dt/.config/xmobar/xmobarrc0"
|
||||
xmproc1 <- spawnPipe "xmobar -x 1 /home/dt/.config/xmobar/xmobarrc2"
|
||||
xmproc2 <- spawnPipe "xmobar -x 2 /home/dt/.config/xmobar/xmobarrc1"
|
||||
-- the xmonad, ya know...what the WM is named after!
|
||||
xmonad $ ewmh def
|
||||
{ manageHook = ( isFullscreen --> doFullFloat ) <+> myManageHook <+> manageDocks
|
||||
-- Run xmonad commands from command line with "xmonadctl command". Commands include:
|
||||
-- shrink, expand, next-layout, default-layout, restart-wm, xterm, kill, refresh, run,
|
||||
-- focus-up, focus-down, swap-up, swap-down, swap-master, sink, quit-wm. You can run
|
||||
-- "xmonadctl 0" to generate full list of commands written to ~/.xsession-errors.
|
||||
, handleEventHook = serverModeEventHookCmd
|
||||
<+> serverModeEventHook
|
||||
<+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
|
||||
<+> docksEventHook
|
||||
, modMask = myModMask
|
||||
, terminal = myTerminal
|
||||
, startupHook = myStartupHook
|
||||
, layoutHook = showWName' myShowWNameTheme myLayoutHook
|
||||
, workspaces = myWorkspaces
|
||||
, borderWidth = myBorderWidth
|
||||
, normalBorderColor = myNormColor
|
||||
, focusedBorderColor = myFocusColor
|
||||
, logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP
|
||||
{ ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x
|
||||
, ppCurrent = xmobarColor "#c3e88d" "" . wrap "[" "]" -- Current workspace in xmobar
|
||||
, ppVisible = xmobarColor "#c3e88d" "" -- Visible but not current workspace
|
||||
, ppHidden = xmobarColor "#82AAFF" "" . wrap "*" "" -- Hidden workspaces in xmobar
|
||||
, ppHiddenNoWindows = xmobarColor "#F07178" "" -- Hidden workspaces (no windows)
|
||||
, ppTitle = xmobarColor "#d0d0d0" "" . shorten 60 -- Title of active window in xmobar
|
||||
, ppSep = "<fc=#666666> | </fc>" -- Separators in xmobar
|
||||
, ppUrgent = xmobarColor "#C45500" "" . wrap "!" "!" -- Urgent workspace
|
||||
, ppExtras = [windowCount] -- # of windows current workspace
|
||||
, ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
|
||||
}
|
||||
} `additionalKeysP` myKeys
|
||||
@@ -0,0 +1,780 @@
|
||||
-- Xmonad is a dynamically tiling X11 window manager that is written and
|
||||
-- configured in Haskell. Official documentation: https://xmonad.org
|
||||
|
||||
-- This is the xmonad configuration of Derek Taylor (DistroTube)
|
||||
-- My YouTube: http://www.youtube.com/c/DistroTube
|
||||
-- My GitLab: http://www.gitlab.com/dwt1/
|
||||
|
||||
-- This config is massively long. It is purposely bloated with a ton of
|
||||
-- examples of what you can do with xmonad. It is written more as a
|
||||
-- study guide rather than a config that you should download and use.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- IMPORTS
|
||||
------------------------------------------------------------------------
|
||||
-- Base
|
||||
import XMonad
|
||||
import System.IO (hPutStrLn)
|
||||
import System.Exit (exitSuccess)
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
-- Actions
|
||||
import XMonad.Actions.CopyWindow (kill1, killAllOtherCopies)
|
||||
import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Actions.MouseResize
|
||||
import XMonad.Actions.Promote
|
||||
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
|
||||
import qualified XMonad.Actions.TreeSelect as TS
|
||||
import XMonad.Actions.WindowGo (runOrRaise)
|
||||
import XMonad.Actions.WithAll (sinkAll, killAll)
|
||||
import qualified XMonad.Actions.Search as S
|
||||
|
||||
-- Data
|
||||
import Data.Char (isSpace)
|
||||
import Data.Monoid
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Tree
|
||||
import qualified Data.Tuple.Extra as TE
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- Hooks
|
||||
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
|
||||
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
|
||||
import XMonad.Hooks.FadeInactive
|
||||
import XMonad.Hooks.ManageDocks (avoidStruts, docksEventHook, manageDocks, ToggleStruts(..))
|
||||
import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat)
|
||||
import XMonad.Hooks.ServerMode
|
||||
import XMonad.Hooks.SetWMName
|
||||
import XMonad.Hooks.WorkspaceHistory
|
||||
|
||||
-- Layouts
|
||||
import XMonad.Layout.GridVariants (Grid(Grid))
|
||||
import XMonad.Layout.SimplestFloat
|
||||
import XMonad.Layout.Spiral
|
||||
import XMonad.Layout.ResizableTile
|
||||
import XMonad.Layout.Tabbed
|
||||
import XMonad.Layout.ThreeColumns
|
||||
|
||||
-- Layouts modifiers
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
|
||||
import XMonad.Layout.Magnifier
|
||||
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
|
||||
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.Renamed (renamed, Rename(Replace))
|
||||
import XMonad.Layout.ShowWName
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
|
||||
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
|
||||
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
|
||||
|
||||
-- Prompt
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.Input
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Man
|
||||
import XMonad.Prompt.Pass
|
||||
import XMonad.Prompt.Shell (shellPrompt)
|
||||
import XMonad.Prompt.Ssh
|
||||
import XMonad.Prompt.XMonad
|
||||
import Control.Arrow (first)
|
||||
|
||||
-- Utilities
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
|
||||
import XMonad.Util.SpawnOnce
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- VARIABLES
|
||||
------------------------------------------------------------------------
|
||||
-- It's nice to assign values to stuff that you will use more than once
|
||||
-- in the config. Setting values for things like font, terminal and editor
|
||||
-- means you only have to change the value here to make changes globally.
|
||||
myFont :: String
|
||||
myFont = "xft:Mononoki Nerd Font:bold:size=9"
|
||||
|
||||
myModMask :: KeyMask
|
||||
myModMask = mod4Mask -- Sets modkey to super/windows key
|
||||
|
||||
myTerminal :: String
|
||||
myTerminal = "alacritty" -- Sets default terminal
|
||||
|
||||
myBrowser :: String
|
||||
myBrowser = myTerminal ++ " -e lynx " -- Sets lynx as browser for tree select
|
||||
-- myBrowser = "firefox " -- Sets firefox as browser for tree select
|
||||
|
||||
myEditor :: String
|
||||
myEditor = "emacsclient -c -a emacs " -- Sets emacs as editor for tree select
|
||||
-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor for tree select
|
||||
|
||||
myBorderWidth :: Dimension
|
||||
myBorderWidth = 2 -- Sets border width for windows
|
||||
|
||||
myNormColor :: String
|
||||
myNormColor = "#292d3e" -- Border color of normal windows
|
||||
|
||||
myFocusColor :: String
|
||||
myFocusColor = "#bbc5ff" -- Border color of focused windows
|
||||
|
||||
altMask :: KeyMask
|
||||
altMask = mod1Mask -- Setting this for use in xprompts
|
||||
|
||||
windowCount :: X (Maybe String)
|
||||
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- AUTOSTART
|
||||
------------------------------------------------------------------------
|
||||
myStartupHook :: X ()
|
||||
myStartupHook = do
|
||||
spawnOnce "nitrogen --restore &"
|
||||
spawnOnce "picom &"
|
||||
spawnOnce "nm-applet &"
|
||||
spawnOnce "volumeicon &"
|
||||
spawnOnce "trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 --tint 0x292d3e --height 18 &"
|
||||
spawnOnce "/usr/bin/emacs --daemon &"
|
||||
-- spawnOnce "kak -d -s mysession &"
|
||||
setWMName "LG3D"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- GRID SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- GridSelect displays items (programs, open windows, etc.) in a 2D grid
|
||||
-- and lets the user select from it with the cursor/hjkl keys or the mouse.
|
||||
myColorizer :: Window -> Bool -> X (String, String)
|
||||
myColorizer = colorRangeFromClassName
|
||||
(0x29,0x2d,0x3e) -- lowest inactive bg
|
||||
(0x29,0x2d,0x3e) -- highest inactive bg
|
||||
(0xc7,0x92,0xea) -- active bg
|
||||
(0xc0,0xa7,0x9a) -- inactive fg
|
||||
(0x29,0x2d,0x3e) -- active fg
|
||||
|
||||
-- gridSelect menu layout
|
||||
mygridConfig :: p -> GSConfig Window
|
||||
mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
spawnSelected' :: [(String, String)] -> X ()
|
||||
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
|
||||
where conf = def
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
-- The lists below are actually 3-tuples for use with gridSelect and treeSelect.
|
||||
-- TreeSelect uses all three values in the 3-tuples but GridSelect only needs first
|
||||
-- two values in each list (see myAppGrid, myBookmarkGrid and myConfigGrid below).
|
||||
myApplications :: [(String, String, String)]
|
||||
myApplications = [ ("Audacity", "audacity", "Graphical cross-platform audio eidtor")
|
||||
, ("Deadbeef", "deadbeef", "Lightweight GUI audio player")
|
||||
, ("Emacs", "emacs", "Much more than a text editor")
|
||||
, ("Firefox", "firefox", "The famous open source web browser")
|
||||
, ("Geany", "geany", "A nice text editor")
|
||||
, ("Geary", "geary", "Email client that is attractive")
|
||||
, ("Gimp", "gimp", "Open source alternative to Photoshop")
|
||||
, ("Kdenlive", "kdenlive", "A great open source video editor")
|
||||
, ("LibreOffice Impress", "loimpress", "For making presentations")
|
||||
, ("LibreOffice Writer", "lowriter", "A fully featured word processor")
|
||||
, ("OBS", "obs", "Open broadcaster software")
|
||||
, ("PCManFM", "pcmanfm", "Lightweight graphical file manager")
|
||||
, ("Simple Terminal", "st", "Suckless simple terminal")
|
||||
, ("Steam", "steam", "Proprietary gaming platform")
|
||||
, ("Surf Browser", "surf suckless.org", "Suckless surf web browser")
|
||||
, ("Xonotic", "xonotic-glx", "A fast-paced first person shooter")
|
||||
]
|
||||
|
||||
myBookmarks :: [(String, String, String)]
|
||||
myBookmarks = [ ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
]
|
||||
|
||||
myConfigs :: [(String, String, String)]
|
||||
myConfigs = [ ("bashrc", myEditor ++ "/home/dt/.bashrc", "the bourne again shell")
|
||||
, ("doom emacs config.el", myEditor ++ "/home/dt/.doom.d/config.el", "doom emacs config")
|
||||
, ("doom emacs init.el", myEditor ++ "/home/dt/.doom.d/init.el", "doom emacs init")
|
||||
, ("dwm", myEditor ++ "/home/dt/dwm-distrotube/config.h", "dwm config file")
|
||||
, ("qtile", myEditor ++ "/home/dt/.config/qtile/config.py", "qtile config")
|
||||
, ("xmonad.hs", myEditor ++ "/home/dt/.xmonad/xmonad.hs", "xmonad config")
|
||||
, ("zshrc", myEditor ++ "/home/dt/.zshrc", "config for the z shell")
|
||||
]
|
||||
|
||||
-- Let's take myApplications, myBookmarks and myConfigs and take only
|
||||
-- the first two values from those 3-tuples (for GridSelect).
|
||||
myAppGrid :: [(String, String)]
|
||||
myAppGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myApplications
|
||||
|
||||
myBookmarkGrid :: [(String, String)]
|
||||
myBookmarkGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myBookmarks
|
||||
|
||||
myConfigGrid :: [(String, String)]
|
||||
myConfigGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myConfigs
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- TREE SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- TreeSelect displays your workspaces or actions in a Tree-like format.
|
||||
-- You can select desired workspace/action with the cursor or hjkl keys.
|
||||
|
||||
treeselectAction :: TS.TSConfig (X ()) -> X ()
|
||||
treeselectAction a = TS.treeselectAction a
|
||||
[ Node (TS.TSNode "applications" "a list of programs I use often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myApplications !! n)
|
||||
(TE.thd3 $ myApplications !! n)
|
||||
(spawn $ TE.snd3 $ myApplications !! n)
|
||||
) [] | n <- [0..(length myApplications - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "bookmarks" "a list of web bookmarks" (return ()))
|
||||
[Node (TS.TSNode(TE.fst3 $ myBookmarks !! n)
|
||||
(TE.thd3 $ myBookmarks !! n)
|
||||
(spawn $ TE.snd3 $ myBookmarks !! n)
|
||||
) [] | n <- [0..(length myBookmarks - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "config files" "config files that edit often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myConfigs !! n)
|
||||
(TE.thd3 $ myConfigs !! n)
|
||||
(spawn $ TE.snd3 $ myConfigs !! n)
|
||||
) [] | n <- [0..(length myConfigs - 1)]
|
||||
]
|
||||
]
|
||||
|
||||
-- Configuration options for treeSelect
|
||||
tsDefaultConfig :: TS.TSConfig a
|
||||
tsDefaultConfig = TS.TSConfig { TS.ts_hidechildren = True
|
||||
, TS.ts_background = 0xdd292d3e
|
||||
, TS.ts_font = myFont
|
||||
, TS.ts_node = (0xffd0d0d0, 0xff202331)
|
||||
, TS.ts_nodealt = (0xffd0d0d0, 0xff292d3e)
|
||||
, TS.ts_highlight = (0xffffffff, 0xff755999)
|
||||
, TS.ts_extra = 0xffd0d0d0
|
||||
, TS.ts_node_width = 200
|
||||
, TS.ts_node_height = 20
|
||||
, TS.ts_originX = 0
|
||||
, TS.ts_originY = 0
|
||||
, TS.ts_indent = 80
|
||||
, TS.ts_navigate = myTreeNavigation
|
||||
}
|
||||
|
||||
-- Keybindings for treeSelect menus. Use h-j-k-l to navigate.
|
||||
-- Use 'o' and 'i' to move forward/back in the workspace history.
|
||||
-- Single KEY's are for top-level nodes. SUPER+KEY are for the
|
||||
-- second-level nodes. SUPER+ALT+KEY are third-level nodes.
|
||||
myTreeNavigation = M.fromList
|
||||
[ ((0, xK_Escape), TS.cancel)
|
||||
, ((0, xK_Return), TS.select)
|
||||
, ((0, xK_space), TS.select)
|
||||
, ((0, xK_Up), TS.movePrev)
|
||||
, ((0, xK_Down), TS.moveNext)
|
||||
, ((0, xK_Left), TS.moveParent)
|
||||
, ((0, xK_Right), TS.moveChild)
|
||||
, ((0, xK_k), TS.movePrev)
|
||||
, ((0, xK_j), TS.moveNext)
|
||||
, ((0, xK_h), TS.moveParent)
|
||||
, ((0, xK_l), TS.moveChild)
|
||||
, ((0, xK_o), TS.moveHistBack)
|
||||
, ((0, xK_i), TS.moveHistForward)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT SETTINGS
|
||||
------------------------------------------------------------------------
|
||||
dtXPConfig :: XPConfig
|
||||
dtXPConfig = def
|
||||
{ font = myFont
|
||||
, bgColor = "#292d3e"
|
||||
, fgColor = "#d0d0d0"
|
||||
, bgHLight = "#c792ea"
|
||||
, fgHLight = "#000000"
|
||||
, borderColor = "#535974"
|
||||
, promptBorderWidth = 0
|
||||
, promptKeymap = dtXPKeymap
|
||||
, position = Top
|
||||
-- , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.3 }
|
||||
, height = 20
|
||||
, historySize = 256
|
||||
, historyFilter = id
|
||||
, defaultText = []
|
||||
, autoComplete = Just 100000 -- set Just 100000 for .1 sec
|
||||
, showCompletionOnTab = False
|
||||
-- , searchPredicate = isPrefixOf
|
||||
, searchPredicate = fuzzyMatch
|
||||
, alwaysHighlight = True
|
||||
, maxComplRows = Nothing -- set to Just 5 for 5 rows
|
||||
}
|
||||
|
||||
-- The same config above minus the autocomplete feature which is annoying
|
||||
-- on certain Xprompts, like the search engine prompts.
|
||||
dtXPConfig' :: XPConfig
|
||||
dtXPConfig' = dtXPConfig
|
||||
{ autoComplete = Nothing
|
||||
}
|
||||
|
||||
-- A list of all of the standard Xmonad prompts and a key press assigned to them.
|
||||
-- These are used in conjunction with keybinding I set later in the config.
|
||||
promptList :: [(String, XPConfig -> X ())]
|
||||
promptList = [ ("m", manPrompt) -- manpages prompt
|
||||
, ("p", passPrompt) -- get passwords (requires 'pass')
|
||||
, ("g", passGeneratePrompt) -- generate passwords (requires 'pass')
|
||||
, ("r", passRemovePrompt) -- remove passwords (requires 'pass')
|
||||
, ("s", sshPrompt) -- ssh prompt
|
||||
, ("x", xmonadPrompt) -- xmonad prompt
|
||||
]
|
||||
|
||||
-- Same as the above list except this is for my custom prompts.
|
||||
promptList' :: [(String, XPConfig -> String -> X (), String)]
|
||||
promptList' = [ ("c", calcPrompt, "qalc") -- requires qalculate-gtk
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- CUSTOM PROMPTS
|
||||
------------------------------------------------------------------------
|
||||
-- calcPrompt requires a cli calculator called qalcualte-gtk.
|
||||
-- You could use this as a template for other custom prompts that
|
||||
-- use command line programs that return a single line of output.
|
||||
calcPrompt :: XPConfig -> String -> X ()
|
||||
calcPrompt c ans =
|
||||
inputPrompt c (trim ans) ?+ \input ->
|
||||
liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c
|
||||
where
|
||||
trim = f . f
|
||||
where f = reverse . dropWhile isSpace
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT KEYMAP (emacs-like key bindings for xprompts)
|
||||
------------------------------------------------------------------------
|
||||
dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ())
|
||||
dtXPKeymap = M.fromList $
|
||||
map (first $ (,) controlMask) -- control + <key>
|
||||
[ (xK_z, killBefore) -- kill line backwards
|
||||
, (xK_k, killAfter) -- kill line forwards
|
||||
, (xK_a, startOfLine) -- move to the beginning of the line
|
||||
, (xK_e, endOfLine) -- move to the end of the line
|
||||
, (xK_m, deleteString Next) -- delete a character foward
|
||||
, (xK_b, moveCursor Prev) -- move cursor forward
|
||||
, (xK_f, moveCursor Next) -- move cursor backward
|
||||
, (xK_BackSpace, killWord Prev) -- kill the previous word
|
||||
, (xK_y, pasteString) -- paste a string
|
||||
, (xK_g, quit) -- quit out of prompt
|
||||
, (xK_bracketleft, quit)
|
||||
]
|
||||
++
|
||||
map (first $ (,) altMask) -- meta key + <key>
|
||||
[ (xK_BackSpace, killWord Prev) -- kill the prev word
|
||||
, (xK_f, moveWord Next) -- move a word forward
|
||||
, (xK_b, moveWord Prev) -- move a word backward
|
||||
, (xK_d, killWord Next) -- kill the next word
|
||||
, (xK_n, moveHistory W.focusUp') -- move up thru history
|
||||
, (xK_p, moveHistory W.focusDown') -- move down thru history
|
||||
]
|
||||
++
|
||||
map (first $ (,) 0) -- <key>
|
||||
[ (xK_Return, setSuccess True >> setDone True)
|
||||
, (xK_KP_Enter, setSuccess True >> setDone True)
|
||||
, (xK_BackSpace, deleteString Prev)
|
||||
, (xK_Delete, deleteString Next)
|
||||
, (xK_Left, moveCursor Prev)
|
||||
, (xK_Right, moveCursor Next)
|
||||
, (xK_Home, startOfLine)
|
||||
, (xK_End, endOfLine)
|
||||
, (xK_Down, moveHistory W.focusUp')
|
||||
, (xK_Up, moveHistory W.focusDown')
|
||||
, (xK_Escape, quit)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SEARCH ENGINES
|
||||
------------------------------------------------------------------------
|
||||
-- Xmonad has several search engines available to use located in
|
||||
-- XMonad.Actions.Search. Additionally, you can add other search engines
|
||||
-- such as those listed below.
|
||||
archwiki, ebay, news, reddit, urban :: S.SearchEngine
|
||||
|
||||
archwiki = S.searchEngine "archwiki" "https://wiki.archlinux.org/index.php?search="
|
||||
ebay = S.searchEngine "ebay" "https://www.ebay.com/sch/i.html?_nkw="
|
||||
news = S.searchEngine "news" "https://news.google.com/search?q="
|
||||
reddit = S.searchEngine "reddit" "https://www.reddit.com/search/?q="
|
||||
urban = S.searchEngine "urban" "https://www.urbandictionary.com/define.php?term="
|
||||
|
||||
-- This is the list of search engines that I want to use. Some are from
|
||||
-- XMonad.Actions.Search, and some are the ones that I added above.
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("a", archwiki)
|
||||
, ("d", S.duckduckgo)
|
||||
, ("e", ebay)
|
||||
, ("g", S.google)
|
||||
, ("h", S.hoogle)
|
||||
, ("i", S.images)
|
||||
, ("n", news)
|
||||
, ("r", reddit)
|
||||
, ("s", S.stackage)
|
||||
, ("t", S.thesaurus)
|
||||
, ("v", S.vocabulary)
|
||||
, ("b", S.wayback)
|
||||
, ("u", urban)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("z", S.amazon)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- WORKSPACES
|
||||
------------------------------------------------------------------------
|
||||
|
||||
myWorkspaces :: [String]
|
||||
myWorkspaces = ["dev", "www", "sys", "doc", "vbox", "chat", "mus", "vid", "gfx"]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MANAGEHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets some rules for certain programs. Examples include forcing certain
|
||||
-- programs to always float, or to always appear on a certain workspace.
|
||||
-- Forcing programs to a certain workspace with a doShift requires xdotool
|
||||
-- if you are using clickable workspaces. You need the className or title
|
||||
-- of the program. Use xprop to get this info.
|
||||
|
||||
myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
|
||||
myManageHook = composeAll
|
||||
-- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
|
||||
-- I'm doing it this way because otherwise I would have to write out
|
||||
-- the full name of my clickable workspaces, which would look like:
|
||||
-- doShift "<action xdotool super+8>gfx</action>"
|
||||
[ className =? "obs" --> doShift ( myWorkspaces !! 7 )
|
||||
, title =? "firefox" --> doShift ( myWorkspaces !! 1 )
|
||||
, className =? "mpv" --> doShift ( myWorkspaces !! 7 )
|
||||
, className =? "vlc" --> doShift ( myWorkspaces !! 7 )
|
||||
, className =? "Gimp" --> doShift ( myWorkspaces !! 8 )
|
||||
, className =? "Gimp" --> doFloat
|
||||
, title =? "Oracle VM VirtualBox Manager" --> doFloat
|
||||
, className =? "VirtualBox Manager" --> doShift ( myWorkspaces !! 4 )
|
||||
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
|
||||
] <+> namedScratchpadManageHook myScratchPads
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LOGHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets opacity for inactive (unfocused) windows. I prefer to not use
|
||||
-- this feature so I've set opacity to 1.0. If you want opacity, set
|
||||
-- this to a value of less than 1 (such as 0.9 for 90% opacity).
|
||||
myLogHook :: X ()
|
||||
myLogHook = fadeInactiveLogHook fadeAmount
|
||||
where fadeAmount = 1.0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LAYOUTS
|
||||
------------------------------------------------------------------------
|
||||
-- Makes setting the spacingRaw simpler to write. The spacingRaw
|
||||
-- module adds a configurable amount of space around windows.
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
|
||||
|
||||
-- Below is a variation of the above except no borders are applied
|
||||
-- if fewer than two windows. So a single window has no gaps.
|
||||
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
|
||||
|
||||
-- Defining a bunch of layouts, many that I don't use.
|
||||
tall = renamed [Replace "tall"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
magnify = renamed [Replace "magnify"]
|
||||
$ magnifier
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
monocle = renamed [Replace "monocle"]
|
||||
$ limitWindows 20 Full
|
||||
floats = renamed [Replace "floats"]
|
||||
$ limitWindows 20 simplestFloat
|
||||
grid = renamed [Replace "grid"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ mkToggle (single MIRROR)
|
||||
$ Grid (16/10)
|
||||
spirals = renamed [Replace "spirals"]
|
||||
$ mySpacing' 8
|
||||
$ spiral (6/7)
|
||||
threeCol = renamed [Replace "threeCol"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
threeRow = renamed [Replace "threeRow"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
-- Mirror takes a layout and rotates it by 90 degrees.
|
||||
-- So we are applying Mirror to the ThreeCol layout.
|
||||
$ Mirror
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
tabs = renamed [Replace "tabs"]
|
||||
-- I cannot add spacing to this layout because it will
|
||||
-- add spacing between window and tabs which looks bad.
|
||||
$ tabbed shrinkText myTabConfig
|
||||
where
|
||||
myTabConfig = def { fontName = "xft:Mononoki Nerd Font:regular:pixelsize=11"
|
||||
, activeColor = "#292d3e"
|
||||
, inactiveColor = "#3e445e"
|
||||
, activeBorderColor = "#292d3e"
|
||||
, inactiveBorderColor = "#292d3e"
|
||||
, activeTextColor = "#ffffff"
|
||||
, inactiveTextColor = "#d0d0d0"
|
||||
}
|
||||
|
||||
-- Theme for showWName which prints current workspace when you change workspaces.
|
||||
myShowWNameTheme :: SWNConfig
|
||||
myShowWNameTheme = def
|
||||
{ swn_font = "xft:Sans:bold:size=60"
|
||||
, swn_fade = 1.0
|
||||
, swn_bgcolor = "#000000"
|
||||
, swn_color = "#FFFFFF"
|
||||
}
|
||||
|
||||
-- The layout hook
|
||||
myLayoutHook = avoidStruts $ mouseResize $ windowArrange $ T.toggleLayouts floats $
|
||||
mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
|
||||
where
|
||||
-- I've commented out the layouts I don't use.
|
||||
myDefaultLayout = tall
|
||||
||| magnify
|
||||
||| noBorders monocle
|
||||
||| floats
|
||||
-- ||| grid
|
||||
||| noBorders tabs
|
||||
-- ||| spirals
|
||||
-- ||| threeCol
|
||||
-- ||| threeRow
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SCRATCHPADS
|
||||
------------------------------------------------------------------------
|
||||
-- Allows to have several floating scratchpads running different applications.
|
||||
-- Import Util.NamedScratchpad. Bind a key to namedScratchpadSpawnAction.
|
||||
myScratchPads :: [NamedScratchpad]
|
||||
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
|
||||
, NS "mocp" spawnMocp findMocp manageMocp
|
||||
]
|
||||
where
|
||||
spawnTerm = myTerminal ++ " -n scratchpad"
|
||||
findTerm = resource =? "scratchpad"
|
||||
manageTerm = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
spawnMocp = myTerminal ++ " -n mocp 'mocp'"
|
||||
findMocp = resource =? "mocp"
|
||||
manageMocp = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- KEYBINDINGS
|
||||
------------------------------------------------------------------------
|
||||
-- I am using the Xmonad.Util.EZConfig module which allows keybindings
|
||||
-- to be written in simpler, emacs-like format.
|
||||
myKeys :: [(String, X ())]
|
||||
myKeys =
|
||||
-- Xmonad
|
||||
[ ("M-C-r", spawn "xmonad --recompile") -- Recompiles xmonad
|
||||
, ("M-S-r", spawn "xmonad --restart") -- Restarts xmonad
|
||||
, ("M-S-q", io exitSuccess) -- Quits xmonad
|
||||
|
||||
-- Open my preferred terminal
|
||||
, ("M-<Return>", spawn myTerminal)
|
||||
|
||||
-- Run Prompt
|
||||
, ("M-S-<Return>", shellPrompt dtXPConfig) -- Shell Prompt
|
||||
|
||||
-- Windows
|
||||
, ("M-S-c", kill1) -- Kill the currently focused client
|
||||
, ("M-S-a", killAll) -- Kill all windows on current workspace
|
||||
|
||||
-- Floating windows
|
||||
, ("M-f", sendMessage (T.Toggle "floats")) -- Toggles my 'floats' layout
|
||||
, ("M-<Delete>", withFocused $ windows . W.sink) -- Push floating window back to tile
|
||||
, ("M-S-<Delete>", sinkAll) -- Push ALL floating windows to tile
|
||||
|
||||
-- Grid Select (CTRL-g followed by a key)
|
||||
, ("C-g g", spawnSelected' myAppGrid) -- grid select favorite apps
|
||||
, ("C-g m", spawnSelected' myBookmarkGrid) -- grid select some bookmarks
|
||||
, ("C-g c", spawnSelected' myConfigGrid) -- grid select useful config files
|
||||
, ("C-g t", goToSelected $ mygridConfig myColorizer) -- goto selected window
|
||||
, ("C-g b", bringSelected $ mygridConfig myColorizer) -- bring selected window
|
||||
|
||||
-- Tree Select/
|
||||
-- tree select actions menu
|
||||
, ("C-t a", treeselectAction tsDefaultConfig)
|
||||
|
||||
-- Windows navigation
|
||||
, ("M-m", windows W.focusMaster) -- Move focus to the master window
|
||||
, ("M-j", windows W.focusDown) -- Move focus to the next window
|
||||
, ("M-k", windows W.focusUp) -- Move focus to the prev window
|
||||
--, ("M-S-m", windows W.swapMaster) -- Swap the focused window and the master window
|
||||
, ("M-S-j", windows W.swapDown) -- Swap focused window with next window
|
||||
, ("M-S-k", windows W.swapUp) -- Swap focused window with prev window
|
||||
, ("M-<Backspace>", promote) -- Moves focused window to master, others maintain order
|
||||
, ("M1-S-<Tab>", rotSlavesDown) -- Rotate all windows except master and keep focus in place
|
||||
, ("M1-C-<Tab>", rotAllDown) -- Rotate all the windows in the current stack
|
||||
--, ("M-S-s", windows copyToAll)
|
||||
, ("M-C-s", killAllOtherCopies)
|
||||
|
||||
-- Layouts
|
||||
, ("M-<Tab>", sendMessage NextLayout) -- Switch to next layout
|
||||
, ("M-C-M1-<Up>", sendMessage Arrange)
|
||||
, ("M-C-M1-<Down>", sendMessage DeArrange)
|
||||
, ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full
|
||||
, ("M-S-<Space>", sendMessage ToggleStruts) -- Toggles struts
|
||||
, ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder
|
||||
, ("M-<KP_Multiply>", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane
|
||||
, ("M-<KP_Divide>", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane
|
||||
, ("M-S-<KP_Multiply>", increaseLimit) -- Increase number of windows
|
||||
, ("M-S-<KP_Divide>", decreaseLimit) -- Decrease number of windows
|
||||
|
||||
, ("M-h", sendMessage Shrink) -- Shrink horiz window width
|
||||
, ("M-l", sendMessage Expand) -- Expand horiz window width
|
||||
, ("M-C-j", sendMessage MirrorShrink) -- Shrink vert window width
|
||||
, ("M-C-k", sendMessage MirrorExpand) -- Exoand vert window width
|
||||
|
||||
-- Workspaces
|
||||
, ("M-.", nextScreen) -- Switch focus to next monitor
|
||||
, ("M-,", prevScreen) -- Switch focus to prev monitor
|
||||
, ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws
|
||||
, ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws
|
||||
|
||||
-- Scratchpads
|
||||
, ("M-C-<Return>", namedScratchpadAction myScratchPads "terminal")
|
||||
, ("M-C-c", namedScratchpadAction myScratchPads "mocp")
|
||||
|
||||
-- Controls for mocp music player.
|
||||
, ("M-u p", spawn "mocp --play")
|
||||
, ("M-u l", spawn "mocp --next")
|
||||
, ("M-u h", spawn "mocp --previous")
|
||||
, ("M-u <Space>", spawn "mocp --toggle-pause")
|
||||
|
||||
-- Emacs (CTRL-e followed by a key)
|
||||
, ("C-e e", spawn "emacsclient -c -a ''") -- start emacs
|
||||
, ("C-e b", spawn "emacsclient -c -a '' --eval '(ibuffer)'") -- list emacs buffers
|
||||
, ("C-e d", spawn "emacsclient -c -a '' --eval '(dired nil)'") -- dired emacs file manager
|
||||
, ("C-e m", spawn "emacsclient -c -a '' --eval '(mu4e)'") -- mu4e emacs email client
|
||||
, ("C-e n", spawn "emacsclient -c -a '' --eval '(elfeed)'") -- elfeed emacs rss client
|
||||
, ("C-e s", spawn "emacsclient -c -a '' --eval '(eshell)'") -- eshell within emacs
|
||||
, ("C-e t", spawn "emacsclient -c -a '' --eval '(+vterm/here nil)'") -- eshell within emacs
|
||||
-- emms is an emacs audio player. I set it to auto start playing in a specific directory.
|
||||
, ("C-e a", spawn "emacsclient -c -a '' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")
|
||||
|
||||
--- My Applications (Super+Alt+Key)
|
||||
, ("M-M1-a", spawn (myTerminal ++ " -e ncpamixer"))
|
||||
, ("M-M1-b", spawn "surf www.youtube.com/c/DistroTube/")
|
||||
, ("M-M1-e", spawn (myTerminal ++ " -e neomutt"))
|
||||
, ("M-M1-f", spawn (myTerminal ++ " -e sh ./.config/vifm/scripts/vifmrun"))
|
||||
, ("M-M1-i", spawn (myTerminal ++ " -e irssi"))
|
||||
, ("M-M1-j", spawn (myTerminal ++ " -e joplin"))
|
||||
, ("M-M1-l", spawn (myTerminal ++ " -e lynx -cfg=~/.lynx/lynx.cfg -lss=~/.lynx/lynx.lss gopher://distro.tube"))
|
||||
, ("M-M1-m", spawn (myTerminal ++ " -e mocp"))
|
||||
, ("M-M1-n", spawn (myTerminal ++ " -e newsboat"))
|
||||
, ("M-M1-p", spawn (myTerminal ++ " -e pianobar"))
|
||||
, ("M-M1-r", spawn (myTerminal ++ " -e rtv"))
|
||||
, ("M-M1-t", spawn (myTerminal ++ " -e toot curses"))
|
||||
, ("M-M1-w", spawn (myTerminal ++ " -e wopr report.xml"))
|
||||
, ("M-M1-y", spawn (myTerminal ++ " -e youtube-viewer"))
|
||||
|
||||
-- Multimedia Keys
|
||||
, ("<XF86AudioPlay>", spawn "cmus toggle")
|
||||
, ("<XF86AudioPrev>", spawn "cmus prev")
|
||||
, ("<XF86AudioNext>", spawn "cmus next")
|
||||
-- , ("<XF86AudioMute>", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04.
|
||||
, ("<XF86AudioLowerVolume>", spawn "amixer set Master 5%- unmute")
|
||||
, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 5%+ unmute")
|
||||
, ("<XF86HomePage>", spawn "firefox")
|
||||
, ("<XF86Search>", safeSpawn "firefox" ["https://www.google.com/"])
|
||||
, ("<XF86Mail>", runOrRaise "geary" (resource =? "thunderbird"))
|
||||
, ("<XF86Calculator>", runOrRaise "gcalctool" (resource =? "gcalctool"))
|
||||
, ("<XF86Eject>", spawn "toggleeject")
|
||||
, ("<Print>", spawn "scrotd 0")
|
||||
]
|
||||
-- Appending search engine prompts to keybindings list.
|
||||
-- Look at "search engines" section of this config for values for "k".
|
||||
++ [("M-s " ++ k, S.promptSearch dtXPConfig' f) | (k,f) <- searchList ]
|
||||
++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
-- Appending some extra xprompts to keybindings list.
|
||||
-- Look at "xprompt settings" section this of config for values for "k".
|
||||
++ [("M-p " ++ k, f dtXPConfig') | (k,f) <- promptList ]
|
||||
++ [("M-p " ++ k, f dtXPConfig' g) | (k,f,g) <- promptList' ]
|
||||
-- The following lines are needed for named scratchpads.
|
||||
where nonNSP = WSIs (return (\ws -> W.tag ws /= "nsp"))
|
||||
nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "nsp"))
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MAIN
|
||||
------------------------------------------------------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Launching three instances of xmobar on their monitors.
|
||||
xmproc0 <- spawnPipe "xmobar -x 0 /home/dt/.config/xmobar/xmobarrc0"
|
||||
xmproc1 <- spawnPipe "xmobar -x 1 /home/dt/.config/xmobar/xmobarrc2"
|
||||
xmproc2 <- spawnPipe "xmobar -x 2 /home/dt/.config/xmobar/xmobarrc1"
|
||||
-- the xmonad, ya know...what the WM is named after!
|
||||
xmonad $ ewmh def
|
||||
{ manageHook = ( isFullscreen --> doFullFloat ) <+> myManageHook <+> manageDocks
|
||||
-- Run xmonad commands from command line with "xmonadctl command". Commands include:
|
||||
-- shrink, expand, next-layout, default-layout, restart-wm, xterm, kill, refresh, run,
|
||||
-- focus-up, focus-down, swap-up, swap-down, swap-master, sink, quit-wm. You can run
|
||||
-- "xmonadctl 0" to generate full list of commands written to ~/.xsession-errors.
|
||||
, handleEventHook = serverModeEventHookCmd
|
||||
<+> serverModeEventHook
|
||||
<+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
|
||||
<+> docksEventHook
|
||||
, modMask = myModMask
|
||||
, terminal = myTerminal
|
||||
, startupHook = myStartupHook
|
||||
, layoutHook = showWName' myShowWNameTheme myLayoutHook
|
||||
, workspaces = myWorkspaces
|
||||
, borderWidth = myBorderWidth
|
||||
, normalBorderColor = myNormColor
|
||||
, focusedBorderColor = myFocusColor
|
||||
, logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP
|
||||
{ ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x
|
||||
, ppCurrent = xmobarColor "#c3e88d" "" . wrap "[" "]" -- Current workspace in xmobar
|
||||
, ppVisible = xmobarColor "#c3e88d" "" -- Visible but not current workspace
|
||||
, ppHidden = xmobarColor "#82AAFF" "" . wrap "*" "" -- Hidden workspaces in xmobar
|
||||
, ppHiddenNoWindows = xmobarColor "#F07178" "" -- Hidden workspaces (no windows)
|
||||
, ppTitle = xmobarColor "#d0d0d0" "" . shorten 60 -- Title of active window in xmobar
|
||||
, ppSep = "<fc=#666666> | </fc>" -- Separators in xmobar
|
||||
, ppUrgent = xmobarColor "#C45500" "" . wrap "!" "!" -- Urgent workspace
|
||||
, ppExtras = [windowCount] -- # of windows current workspace
|
||||
, ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
|
||||
}
|
||||
} `additionalKeysP` myKeys
|
||||
@@ -0,0 +1,867 @@
|
||||
-- Xmonad is a dynamically tiling X11 window manager that is written and
|
||||
-- configured in Haskell. Official documentation: https://xmonad.org
|
||||
|
||||
-- This is the xmonad configuration of Derek Taylor (DistroTube)
|
||||
-- My YouTube: http://www.youtube.com/c/DistroTube
|
||||
-- My GitLab: http://www.gitlab.com/dwt1/
|
||||
|
||||
-- This config is massively long. It is purposely bloated with a ton of
|
||||
-- examples of what you can do with xmonad. It is written more as a
|
||||
-- study guide rather than a config that you should download and use.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- IMPORTS
|
||||
------------------------------------------------------------------------
|
||||
-- Base
|
||||
import XMonad
|
||||
import System.IO (hPutStrLn)
|
||||
import System.Exit (exitSuccess)
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
-- Actions
|
||||
import XMonad.Actions.CopyWindow (kill1, killAllOtherCopies)
|
||||
import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Actions.MouseResize
|
||||
import XMonad.Actions.Promote
|
||||
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
|
||||
import qualified XMonad.Actions.TreeSelect as TS
|
||||
import XMonad.Actions.WindowGo (runOrRaise)
|
||||
import XMonad.Actions.WithAll (sinkAll, killAll)
|
||||
import qualified XMonad.Actions.Search as S
|
||||
|
||||
-- Data
|
||||
import Data.Char (isSpace)
|
||||
import Data.Monoid
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Tree
|
||||
import qualified Data.Tuple.Extra as TE
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- Hooks
|
||||
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
|
||||
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
|
||||
import XMonad.Hooks.FadeInactive
|
||||
import XMonad.Hooks.ManageDocks (avoidStruts, docksEventHook, manageDocks, ToggleStruts(..))
|
||||
import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat)
|
||||
import XMonad.Hooks.ServerMode
|
||||
import XMonad.Hooks.SetWMName
|
||||
import XMonad.Hooks.WorkspaceHistory
|
||||
|
||||
-- Layouts
|
||||
import XMonad.Layout.GridVariants (Grid(Grid))
|
||||
import XMonad.Layout.SimplestFloat
|
||||
import XMonad.Layout.Spiral
|
||||
import XMonad.Layout.ResizableTile
|
||||
import XMonad.Layout.Tabbed
|
||||
import XMonad.Layout.ThreeColumns
|
||||
|
||||
-- Layouts modifiers
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
|
||||
import XMonad.Layout.Magnifier
|
||||
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
|
||||
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.Renamed (renamed, Rename(Replace))
|
||||
import XMonad.Layout.ShowWName
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
|
||||
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
|
||||
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
|
||||
|
||||
-- Prompt
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.Input
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Man
|
||||
import XMonad.Prompt.Pass
|
||||
import XMonad.Prompt.Shell (shellPrompt)
|
||||
import XMonad.Prompt.Ssh
|
||||
import XMonad.Prompt.XMonad
|
||||
import Control.Arrow (first)
|
||||
|
||||
-- Utilities
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
|
||||
import XMonad.Util.SpawnOnce
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- VARIABLES
|
||||
------------------------------------------------------------------------
|
||||
-- It's nice to assign values to stuff that you will use more than once
|
||||
-- in the config. Setting values for things like font, terminal and editor
|
||||
-- means you only have to change the value here to make changes globally.
|
||||
myFont :: String
|
||||
myFont = "xft:Mononoki Nerd Font:bold:size=9"
|
||||
|
||||
myModMask :: KeyMask
|
||||
myModMask = mod4Mask -- Sets modkey to super/windows key
|
||||
|
||||
myTerminal :: String
|
||||
myTerminal = "alacritty" -- Sets default terminal
|
||||
|
||||
myBrowser :: String
|
||||
myBrowser = myTerminal ++ " -e lynx " -- Sets lynx as browser for tree select
|
||||
-- myBrowser = "firefox " -- Sets firefox as browser for tree select
|
||||
|
||||
myEditor :: String
|
||||
myEditor = "emacsclient -c -a emacs " -- Sets emacs as editor for tree select
|
||||
-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor for tree select
|
||||
|
||||
myBorderWidth :: Dimension
|
||||
myBorderWidth = 2 -- Sets border width for windows
|
||||
|
||||
myNormColor :: String
|
||||
myNormColor = "#292d3e" -- Border color of normal windows
|
||||
|
||||
myFocusColor :: String
|
||||
myFocusColor = "#bbc5ff" -- Border color of focused windows
|
||||
|
||||
altMask :: KeyMask
|
||||
altMask = mod1Mask -- Setting this for use in xprompts
|
||||
|
||||
windowCount :: X (Maybe String)
|
||||
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- AUTOSTART
|
||||
------------------------------------------------------------------------
|
||||
myStartupHook :: X ()
|
||||
myStartupHook = do
|
||||
spawnOnce "nitrogen --restore &"
|
||||
spawnOnce "picom &"
|
||||
spawnOnce "nm-applet &"
|
||||
spawnOnce "volumeicon &"
|
||||
spawnOnce "trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 --tint 0x292d3e --height 18 &"
|
||||
spawnOnce "/usr/bin/emacs --daemon &"
|
||||
-- spawnOnce "kak -d -s mysession &"
|
||||
setWMName "LG3D"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- GRID SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- GridSelect displays items (programs, open windows, etc.) in a 2D grid
|
||||
-- and lets the user select from it with the cursor/hjkl keys or the mouse.
|
||||
myColorizer :: Window -> Bool -> X (String, String)
|
||||
myColorizer = colorRangeFromClassName
|
||||
(0x29,0x2d,0x3e) -- lowest inactive bg
|
||||
(0x29,0x2d,0x3e) -- highest inactive bg
|
||||
(0xc7,0x92,0xea) -- active bg
|
||||
(0xc0,0xa7,0x9a) -- inactive fg
|
||||
(0x29,0x2d,0x3e) -- active fg
|
||||
|
||||
-- gridSelect menu layout
|
||||
mygridConfig :: p -> GSConfig Window
|
||||
mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
spawnSelected' :: [(String, String)] -> X ()
|
||||
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
|
||||
where conf = def
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
-- The lists below are actually 3-tuples for use with gridSelect and treeSelect.
|
||||
-- TreeSelect uses all three values in the 3-tuples but GridSelect only needs first
|
||||
-- two values in each list (see myAppGrid, myBookmarkGrid and myConfigGrid below).
|
||||
myApplications :: [(String, String, String)]
|
||||
myApplications = [ ("Audacity", "audacity", "Graphical cross-platform audio eidtor")
|
||||
, ("Deadbeef", "deadbeef", "Lightweight GUI audio player")
|
||||
, ("Emacs", "emacs", "Much more than a text editor")
|
||||
, ("Firefox", "firefox", "The famous open source web browser")
|
||||
, ("Geany", "geany", "A nice text editor")
|
||||
, ("Geary", "geary", "Email client that is attractive")
|
||||
, ("Gimp", "gimp", "Open source alternative to Photoshop")
|
||||
, ("Kdenlive", "kdenlive", "A great open source video editor")
|
||||
, ("LibreOffice Impress", "loimpress", "For making presentations")
|
||||
, ("LibreOffice Writer", "lowriter", "A fully featured word processor")
|
||||
, ("OBS", "obs", "Open broadcaster software")
|
||||
, ("PCManFM", "pcmanfm", "Lightweight graphical file manager")
|
||||
, ("Simple Terminal", "st", "Suckless simple terminal")
|
||||
, ("Steam", "steam", "Proprietary gaming platform")
|
||||
, ("Surf Browser", "surf suckless.org", "Suckless surf web browser")
|
||||
, ("Xonotic", "xonotic-glx", "A fast-paced first person shooter")
|
||||
]
|
||||
|
||||
myBookmarks :: [(String, String, String)]
|
||||
myBookmarks = [ ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
, ("Site Name", myBrowser ++ "https://www.distrotube.com", "Official website for DistroTube")
|
||||
]
|
||||
|
||||
myConfigs :: [(String, String, String)]
|
||||
myConfigs = [ ("bashrc", myEditor ++ "/home/dt/.bashrc", "the bourne again shell")
|
||||
, ("doom emacs config.el", myEditor ++ "/home/dt/.doom.d/config.el", "doom emacs config")
|
||||
, ("doom emacs init.el", myEditor ++ "/home/dt/.doom.d/init.el", "doom emacs init")
|
||||
, ("dwm", myEditor ++ "/home/dt/dwm-distrotube/config.h", "dwm config file")
|
||||
, ("qtile", myEditor ++ "/home/dt/.config/qtile/config.py", "qtile config")
|
||||
, ("xmonad.hs", myEditor ++ "/home/dt/.xmonad/xmonad.hs", "xmonad config")
|
||||
, ("zshrc", myEditor ++ "/home/dt/.zshrc", "config for the z shell")
|
||||
]
|
||||
|
||||
-- Let's take myApplications, myBookmarks and myConfigs and take only
|
||||
-- the first two values from those 3-tuples (for GridSelect).
|
||||
myAppGrid :: [(String, String)]
|
||||
myAppGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myApplications
|
||||
|
||||
myBookmarkGrid :: [(String, String)]
|
||||
myBookmarkGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myBookmarks
|
||||
|
||||
myConfigGrid :: [(String, String)]
|
||||
myConfigGrid = [ (a,b) | (a,b,c) <- xs]
|
||||
where xs = myConfigs
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- TREE SELECT
|
||||
------------------------------------------------------------------------
|
||||
-- TreeSelect displays your workspaces or actions in a Tree-like format.
|
||||
-- You can select desired workspace/action with the cursor or hjkl keys.
|
||||
|
||||
treeselectAction :: TS.TSConfig (X ()) -> X ()
|
||||
treeselectAction a = TS.treeselectAction a
|
||||
[ Node (TS.TSNode "applications" "a list of programs I use often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myApplications !! n)
|
||||
(TE.thd3 $ myApplications !! n)
|
||||
(spawn $ TE.snd3 $ myApplications !! n)
|
||||
) [] | n <- [0..(length myApplications - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "bookmarks" "a list of web bookmarks" (return ()))
|
||||
[Node (TS.TSNode(TE.fst3 $ myBookmarks !! n)
|
||||
(TE.thd3 $ myBookmarks !! n)
|
||||
(spawn $ TE.snd3 $ myBookmarks !! n)
|
||||
) [] | n <- [0..(length myBookmarks - 1)]
|
||||
]
|
||||
, Node (TS.TSNode "config files" "config files that edit often" (return ()))
|
||||
[Node (TS.TSNode (TE.fst3 $ myConfigs !! n)
|
||||
(TE.thd3 $ myConfigs !! n)
|
||||
(spawn $ TE.snd3 $ myConfigs !! n)
|
||||
) [] | n <- [0..(length myConfigs - 1)]
|
||||
]
|
||||
]
|
||||
|
||||
-- Configuration options for treeSelect
|
||||
tsDefaultConfig :: TS.TSConfig a
|
||||
tsDefaultConfig = TS.TSConfig { TS.ts_hidechildren = True
|
||||
, TS.ts_background = 0xdd292d3e
|
||||
, TS.ts_font = myFont
|
||||
, TS.ts_node = (0xffd0d0d0, 0xff202331)
|
||||
, TS.ts_nodealt = (0xffd0d0d0, 0xff292d3e)
|
||||
, TS.ts_highlight = (0xffffffff, 0xff755999)
|
||||
, TS.ts_extra = 0xffd0d0d0
|
||||
, TS.ts_node_width = 200
|
||||
, TS.ts_node_height = 20
|
||||
, TS.ts_originX = 0
|
||||
, TS.ts_originY = 0
|
||||
, TS.ts_indent = 80
|
||||
, TS.ts_navigate = myTreeNavigation
|
||||
}
|
||||
|
||||
-- Keybindings for treeSelect menus. Use h-j-k-l to navigate.
|
||||
-- Use 'o' and 'i' to move forward/back in the workspace history.
|
||||
-- Single KEY's are for top-level nodes. SUPER+KEY are for the
|
||||
-- second-level nodes. SUPER+ALT+KEY are third-level nodes.
|
||||
myTreeNavigation = M.fromList
|
||||
[ ((0, xK_Escape), TS.cancel)
|
||||
, ((0, xK_Return), TS.select)
|
||||
, ((0, xK_space), TS.select)
|
||||
, ((0, xK_Up), TS.movePrev)
|
||||
, ((0, xK_Down), TS.moveNext)
|
||||
, ((0, xK_Left), TS.moveParent)
|
||||
, ((0, xK_Right), TS.moveChild)
|
||||
, ((0, xK_k), TS.movePrev)
|
||||
, ((0, xK_j), TS.moveNext)
|
||||
, ((0, xK_h), TS.moveParent)
|
||||
, ((0, xK_l), TS.moveChild)
|
||||
, ((0, xK_o), TS.moveHistBack)
|
||||
, ((0, xK_i), TS.moveHistForward)
|
||||
, ((0, xK_d), TS.moveTo ["dev"])
|
||||
, ((0, xK_g), TS.moveTo ["graphics"])
|
||||
, ((0, xK_m), TS.moveTo ["music"])
|
||||
, ((0, xK_v), TS.moveTo ["video"])
|
||||
, ((0, xK_w), TS.moveTo ["web"])
|
||||
, ((mod4Mask, xK_b), TS.moveTo ["web", "browser"])
|
||||
, ((mod4Mask, xK_c), TS.moveTo ["web", "chat"])
|
||||
, ((mod4Mask, xK_m), TS.moveTo ["web", "email"])
|
||||
, ((mod4Mask, xK_r), TS.moveTo ["web", "rss"])
|
||||
, ((mod4Mask, xK_w), TS.moveTo ["web", "web conference"])
|
||||
, ((mod4Mask, xK_d), TS.moveTo ["dev", "docs"])
|
||||
, ((mod4Mask, xK_e), TS.moveTo ["dev", "emacs"])
|
||||
, ((mod4Mask, xK_f), TS.moveTo ["dev", "files"])
|
||||
, ((mod4Mask, xK_p), TS.moveTo ["dev", "programming"])
|
||||
, ((mod4Mask, xK_t), TS.moveTo ["dev", "terminal"])
|
||||
, ((mod4Mask, xK_z), TS.moveTo ["dev", "virtualization"])
|
||||
, ((mod4Mask, xK_g), TS.moveTo ["graphics", "gimp"])
|
||||
, ((mod4Mask, xK_i), TS.moveTo ["graphics", "image viewer"])
|
||||
, ((mod4Mask, xK_a), TS.moveTo ["music", "audio editor"])
|
||||
, ((mod4Mask, xK_u), TS.moveTo ["music", "music player"])
|
||||
, ((mod4Mask, xK_o), TS.moveTo ["video", "obs"])
|
||||
, ((mod4Mask, xK_v), TS.moveTo ["video", "video player"])
|
||||
, ((mod4Mask, xK_k), TS.moveTo ["video", "kdenlive"])
|
||||
, ((mod4Mask .|. altMask, xK_h), TS.moveTo ["dev", "programming", "haskell"])
|
||||
, ((mod4Mask .|. altMask, xK_p), TS.moveTo ["dev", "programming", "python"])
|
||||
, ((mod4Mask .|. altMask, xK_s), TS.moveTo ["dev", "programming", "shell"])
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT SETTINGS
|
||||
------------------------------------------------------------------------
|
||||
dtXPConfig :: XPConfig
|
||||
dtXPConfig = def
|
||||
{ font = myFont
|
||||
, bgColor = "#292d3e"
|
||||
, fgColor = "#d0d0d0"
|
||||
, bgHLight = "#c792ea"
|
||||
, fgHLight = "#000000"
|
||||
, borderColor = "#535974"
|
||||
, promptBorderWidth = 0
|
||||
, promptKeymap = dtXPKeymap
|
||||
, position = Top
|
||||
-- , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.3 }
|
||||
, height = 20
|
||||
, historySize = 256
|
||||
, historyFilter = id
|
||||
, defaultText = []
|
||||
, autoComplete = Just 100000 -- set Just 100000 for .1 sec
|
||||
, showCompletionOnTab = False
|
||||
-- , searchPredicate = isPrefixOf
|
||||
, searchPredicate = fuzzyMatch
|
||||
, alwaysHighlight = True
|
||||
, maxComplRows = Nothing -- set to Just 5 for 5 rows
|
||||
}
|
||||
|
||||
-- The same config above minus the autocomplete feature which is annoying
|
||||
-- on certain Xprompts, like the search engine prompts.
|
||||
dtXPConfig' :: XPConfig
|
||||
dtXPConfig' = dtXPConfig
|
||||
{ autoComplete = Nothing
|
||||
}
|
||||
|
||||
-- A list of all of the standard Xmonad prompts and a key press assigned to them.
|
||||
-- These are used in conjunction with keybinding I set later in the config.
|
||||
promptList :: [(String, XPConfig -> X ())]
|
||||
promptList = [ ("m", manPrompt) -- manpages prompt
|
||||
, ("p", passPrompt) -- get passwords (requires 'pass')
|
||||
, ("g", passGeneratePrompt) -- generate passwords (requires 'pass')
|
||||
, ("r", passRemovePrompt) -- remove passwords (requires 'pass')
|
||||
, ("s", sshPrompt) -- ssh prompt
|
||||
, ("x", xmonadPrompt) -- xmonad prompt
|
||||
]
|
||||
|
||||
-- Same as the above list except this is for my custom prompts.
|
||||
promptList' :: [(String, XPConfig -> String -> X (), String)]
|
||||
promptList' = [ ("c", calcPrompt, "qalc") -- requires qalculate-gtk
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- CUSTOM PROMPTS
|
||||
------------------------------------------------------------------------
|
||||
-- calcPrompt requires a cli calculator called qalcualte-gtk.
|
||||
-- You could use this as a template for other custom prompts that
|
||||
-- use command line programs that return a single line of output.
|
||||
calcPrompt :: XPConfig -> String -> X ()
|
||||
calcPrompt c ans =
|
||||
inputPrompt c (trim ans) ?+ \input ->
|
||||
liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c
|
||||
where
|
||||
trim = f . f
|
||||
where f = reverse . dropWhile isSpace
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- XPROMPT KEYMAP (emacs-like key bindings for xprompts)
|
||||
------------------------------------------------------------------------
|
||||
dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ())
|
||||
dtXPKeymap = M.fromList $
|
||||
map (first $ (,) controlMask) -- control + <key>
|
||||
[ (xK_z, killBefore) -- kill line backwards
|
||||
, (xK_k, killAfter) -- kill line forwards
|
||||
, (xK_a, startOfLine) -- move to the beginning of the line
|
||||
, (xK_e, endOfLine) -- move to the end of the line
|
||||
, (xK_m, deleteString Next) -- delete a character foward
|
||||
, (xK_b, moveCursor Prev) -- move cursor forward
|
||||
, (xK_f, moveCursor Next) -- move cursor backward
|
||||
, (xK_BackSpace, killWord Prev) -- kill the previous word
|
||||
, (xK_y, pasteString) -- paste a string
|
||||
, (xK_g, quit) -- quit out of prompt
|
||||
, (xK_bracketleft, quit)
|
||||
]
|
||||
++
|
||||
map (first $ (,) altMask) -- meta key + <key>
|
||||
[ (xK_BackSpace, killWord Prev) -- kill the prev word
|
||||
, (xK_f, moveWord Next) -- move a word forward
|
||||
, (xK_b, moveWord Prev) -- move a word backward
|
||||
, (xK_d, killWord Next) -- kill the next word
|
||||
, (xK_n, moveHistory W.focusUp') -- move up thru history
|
||||
, (xK_p, moveHistory W.focusDown') -- move down thru history
|
||||
]
|
||||
++
|
||||
map (first $ (,) 0) -- <key>
|
||||
[ (xK_Return, setSuccess True >> setDone True)
|
||||
, (xK_KP_Enter, setSuccess True >> setDone True)
|
||||
, (xK_BackSpace, deleteString Prev)
|
||||
, (xK_Delete, deleteString Next)
|
||||
, (xK_Left, moveCursor Prev)
|
||||
, (xK_Right, moveCursor Next)
|
||||
, (xK_Home, startOfLine)
|
||||
, (xK_End, endOfLine)
|
||||
, (xK_Down, moveHistory W.focusUp')
|
||||
, (xK_Up, moveHistory W.focusDown')
|
||||
, (xK_Escape, quit)
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SEARCH ENGINES
|
||||
------------------------------------------------------------------------
|
||||
-- Xmonad has several search engines available to use located in
|
||||
-- XMonad.Actions.Search. Additionally, you can add other search engines
|
||||
-- such as those listed below.
|
||||
archwiki, ebay, news, reddit, urban :: S.SearchEngine
|
||||
|
||||
archwiki = S.searchEngine "archwiki" "https://wiki.archlinux.org/index.php?search="
|
||||
ebay = S.searchEngine "ebay" "https://www.ebay.com/sch/i.html?_nkw="
|
||||
news = S.searchEngine "news" "https://news.google.com/search?q="
|
||||
reddit = S.searchEngine "reddit" "https://www.reddit.com/search/?q="
|
||||
urban = S.searchEngine "urban" "https://www.urbandictionary.com/define.php?term="
|
||||
|
||||
-- This is the list of search engines that I want to use. Some are from
|
||||
-- XMonad.Actions.Search, and some are the ones that I added above.
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("a", archwiki)
|
||||
, ("d", S.duckduckgo)
|
||||
, ("e", ebay)
|
||||
, ("g", S.google)
|
||||
, ("h", S.hoogle)
|
||||
, ("i", S.images)
|
||||
, ("n", news)
|
||||
, ("r", reddit)
|
||||
, ("s", S.stackage)
|
||||
, ("t", S.thesaurus)
|
||||
, ("v", S.vocabulary)
|
||||
, ("b", S.wayback)
|
||||
, ("u", urban)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("z", S.amazon)
|
||||
]
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- WORKSPACES
|
||||
------------------------------------------------------------------------
|
||||
-- My workspaces are clickable meaning that the mouse can be used to switch
|
||||
-- workspaces. This requires xdotool. You need to use UnsafeStdInReader instead
|
||||
-- of simply StdInReader in xmobar config so you can pass actions to it.
|
||||
|
||||
{- Commented out clickable xmobar workspaces to use TreeSelect workspaces.
|
||||
|
||||
xmobarEscape :: String -> String
|
||||
xmobarEscape = concatMap doubleLts
|
||||
where
|
||||
doubleLts '<' = "<<"
|
||||
doubleLts x = [x]
|
||||
|
||||
myWorkspaces :: [String]
|
||||
myWorkspaces = clickable . map xmobarEscape
|
||||
$ ["dev", "www", "sys", "doc", "vbox", "chat", "mus", "vid", "gfx"]
|
||||
where
|
||||
clickable l = [ "<action=xdotool key super+" ++ show n ++ ">" ++ ws ++ "</action>" |
|
||||
(i,ws) <- zip [1..9] l,
|
||||
let n = i ]
|
||||
|
||||
End of comment -}
|
||||
|
||||
-- TreeSelect workspaces
|
||||
myWorkspaces :: Forest String
|
||||
myWorkspaces = [ Node "dev"
|
||||
[ Node "terminal" []
|
||||
, Node "emacs" []
|
||||
, Node "docs" []
|
||||
, Node "files" []
|
||||
, Node "programming"
|
||||
[ Node "haskell" []
|
||||
, Node "python" []
|
||||
, Node "shell" []
|
||||
]
|
||||
, Node "virtualization" []
|
||||
]
|
||||
, Node "web"
|
||||
[ Node "browser" []
|
||||
, Node "chat" []
|
||||
, Node "email" []
|
||||
, Node "rss" []
|
||||
, Node "web conference" []
|
||||
]
|
||||
, Node "graphics"
|
||||
[ Node "gimp" []
|
||||
, Node "image viewer" []
|
||||
]
|
||||
, Node "music"
|
||||
[ Node "audio editor" []
|
||||
, Node "music player" []
|
||||
]
|
||||
, Node "video"
|
||||
[ Node "obs" []
|
||||
, Node "kdenlive" []
|
||||
, Node "video player" []
|
||||
]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MANAGEHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets some rules for certain programs. Examples include forcing certain
|
||||
-- programs to always float, or to always appear on a certain workspace.
|
||||
-- Forcing programs to a certain workspace with a doShift requires xdotool
|
||||
-- if you are using clickable workspaces. You need the className or title
|
||||
-- of the program. Use xprop to get this info.
|
||||
|
||||
myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
|
||||
myManageHook = composeAll
|
||||
-- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
|
||||
-- I'm doing it this way because otherwise I would have to write out
|
||||
-- the full name of my clickable workspaces, which would look like:
|
||||
-- doShift "<action xdotool super+8>gfx</action>"
|
||||
[ className =? "obs" --> doShift ( "video.obs" )
|
||||
, title =? "firefox" --> doShift ( "web.browser" )
|
||||
, title =? "qutebrowser" --> doShift ( "web.browser" )
|
||||
, className =? "mpv" --> doShift ( "video.movie player" )
|
||||
, className =? "vlc" --> doShift ( "video.movie player" )
|
||||
, className =? "Gimp" --> doShift ( "graphics.gimp")
|
||||
, className =? "Gimp" --> doFloat
|
||||
, title =? "Oracle VM VirtualBox Manager" --> doFloat
|
||||
, className =? "VirtualBox Manager" --> doShift ( "dev.virtualization" )
|
||||
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
|
||||
] <+> namedScratchpadManageHook myScratchPads
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LOGHOOK
|
||||
------------------------------------------------------------------------
|
||||
-- Sets opacity for inactive (unfocused) windows. I prefer to not use
|
||||
-- this feature so I've set opacity to 1.0. If you want opacity, set
|
||||
-- this to a value of less than 1 (such as 0.9 for 90% opacity).
|
||||
myLogHook :: X ()
|
||||
myLogHook = fadeInactiveLogHook fadeAmount
|
||||
where fadeAmount = 1.0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- LAYOUTS
|
||||
------------------------------------------------------------------------
|
||||
-- Makes setting the spacingRaw simpler to write. The spacingRaw
|
||||
-- module adds a configurable amount of space around windows.
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
|
||||
|
||||
-- Below is a variation of the above except no borders are applied
|
||||
-- if fewer than two windows. So a single window has no gaps.
|
||||
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
|
||||
|
||||
-- Defining a bunch of layouts, many that I don't use.
|
||||
tall = renamed [Replace "tall"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
magnify = renamed [Replace "magnify"]
|
||||
$ magnifier
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
monocle = renamed [Replace "monocle"]
|
||||
$ limitWindows 20 Full
|
||||
floats = renamed [Replace "floats"]
|
||||
$ limitWindows 20 simplestFloat
|
||||
grid = renamed [Replace "grid"]
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ mkToggle (single MIRROR)
|
||||
$ Grid (16/10)
|
||||
spirals = renamed [Replace "spirals"]
|
||||
$ mySpacing' 8
|
||||
$ spiral (6/7)
|
||||
threeCol = renamed [Replace "threeCol"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
threeRow = renamed [Replace "threeRow"]
|
||||
$ limitWindows 7
|
||||
$ mySpacing' 4
|
||||
-- Mirror takes a layout and rotates it by 90 degrees.
|
||||
-- So we are applying Mirror to the ThreeCol layout.
|
||||
$ Mirror
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
tabs = renamed [Replace "tabs"]
|
||||
-- I cannot add spacing to this layout because it will
|
||||
-- add spacing between window and tabs which looks bad.
|
||||
$ tabbed shrinkText myTabConfig
|
||||
where
|
||||
myTabConfig = def { fontName = "xft:Mononoki Nerd Font:regular:pixelsize=11"
|
||||
, activeColor = "#292d3e"
|
||||
, inactiveColor = "#3e445e"
|
||||
, activeBorderColor = "#292d3e"
|
||||
, inactiveBorderColor = "#292d3e"
|
||||
, activeTextColor = "#ffffff"
|
||||
, inactiveTextColor = "#d0d0d0"
|
||||
}
|
||||
|
||||
-- Theme for showWName which prints current workspace when you change workspaces.
|
||||
myShowWNameTheme :: SWNConfig
|
||||
myShowWNameTheme = def
|
||||
{ swn_font = "xft:Sans:bold:size=60"
|
||||
, swn_fade = 1.0
|
||||
, swn_bgcolor = "#000000"
|
||||
, swn_color = "#FFFFFF"
|
||||
}
|
||||
|
||||
-- The layout hook
|
||||
myLayoutHook = avoidStruts $ mouseResize $ windowArrange $ T.toggleLayouts floats $
|
||||
mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
|
||||
where
|
||||
-- I've commented out the layouts I don't use.
|
||||
myDefaultLayout = tall
|
||||
||| magnify
|
||||
||| noBorders monocle
|
||||
||| floats
|
||||
-- ||| grid
|
||||
||| noBorders tabs
|
||||
-- ||| spirals
|
||||
-- ||| threeCol
|
||||
-- ||| threeRow
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- SCRATCHPADS
|
||||
------------------------------------------------------------------------
|
||||
-- Allows to have several floating scratchpads running different applications.
|
||||
-- Import Util.NamedScratchpad. Bind a key to namedScratchpadSpawnAction.
|
||||
myScratchPads :: [NamedScratchpad]
|
||||
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
|
||||
, NS "mocp" spawnMocp findMocp manageMocp
|
||||
]
|
||||
where
|
||||
spawnTerm = myTerminal ++ " -n scratchpad"
|
||||
findTerm = resource =? "scratchpad"
|
||||
manageTerm = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
spawnMocp = myTerminal ++ " -n mocp 'mocp'"
|
||||
findMocp = resource =? "mocp"
|
||||
manageMocp = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- KEYBINDINGS
|
||||
------------------------------------------------------------------------
|
||||
-- I am using the Xmonad.Util.EZConfig module which allows keybindings
|
||||
-- to be written in simpler, emacs-like format.
|
||||
myKeys :: [(String, X ())]
|
||||
myKeys =
|
||||
-- Xmonad
|
||||
[ ("M-C-r", spawn "xmonad --recompile") -- Recompiles xmonad
|
||||
, ("M-S-r", spawn "xmonad --restart") -- Restarts xmonad
|
||||
, ("M-S-q", io exitSuccess) -- Quits xmonad
|
||||
|
||||
-- Open my preferred terminal
|
||||
, ("M-<Return>", spawn myTerminal)
|
||||
|
||||
-- Run Prompt
|
||||
, ("M-S-<Return>", shellPrompt dtXPConfig) -- Shell Prompt
|
||||
|
||||
-- Windows
|
||||
, ("M-S-c", kill1) -- Kill the currently focused client
|
||||
, ("M-S-a", killAll) -- Kill all windows on current workspace
|
||||
|
||||
-- Floating windows
|
||||
, ("M-f", sendMessage (T.Toggle "floats")) -- Toggles my 'floats' layout
|
||||
, ("M-<Delete>", withFocused $ windows . W.sink) -- Push floating window back to tile
|
||||
, ("M-S-<Delete>", sinkAll) -- Push ALL floating windows to tile
|
||||
|
||||
-- Grid Select (CTRL-g followed by a key)
|
||||
, ("C-g g", spawnSelected' myAppGrid) -- grid select favorite apps
|
||||
, ("C-g m", spawnSelected' myBookmarkGrid) -- grid select some bookmarks
|
||||
, ("C-g c", spawnSelected' myConfigGrid) -- grid select useful config files
|
||||
, ("C-g t", goToSelected $ mygridConfig myColorizer) -- goto selected window
|
||||
, ("C-g b", bringSelected $ mygridConfig myColorizer) -- bring selected window
|
||||
|
||||
-- Tree Select/
|
||||
-- tree select actions menu
|
||||
, ("C-t a", treeselectAction tsDefaultConfig)
|
||||
-- tree select workspaces menu
|
||||
, ("C-t t", TS.treeselectWorkspace tsDefaultConfig myWorkspaces W.greedyView)
|
||||
-- tree select choose workspace to send window
|
||||
, ("C-t g", TS.treeselectWorkspace tsDefaultConfig myWorkspaces W.shift)
|
||||
|
||||
-- Windows navigation
|
||||
, ("M-m", windows W.focusMaster) -- Move focus to the master window
|
||||
, ("M-j", windows W.focusDown) -- Move focus to the next window
|
||||
, ("M-k", windows W.focusUp) -- Move focus to the prev window
|
||||
--, ("M-S-m", windows W.swapMaster) -- Swap the focused window and the master window
|
||||
, ("M-S-j", windows W.swapDown) -- Swap focused window with next window
|
||||
, ("M-S-k", windows W.swapUp) -- Swap focused window with prev window
|
||||
, ("M-<Backspace>", promote) -- Moves focused window to master, others maintain order
|
||||
, ("M1-S-<Tab>", rotSlavesDown) -- Rotate all windows except master and keep focus in place
|
||||
, ("M1-C-<Tab>", rotAllDown) -- Rotate all the windows in the current stack
|
||||
--, ("M-S-s", windows copyToAll)
|
||||
, ("M-C-s", killAllOtherCopies)
|
||||
|
||||
-- Layouts
|
||||
, ("M-<Tab>", sendMessage NextLayout) -- Switch to next layout
|
||||
, ("M-C-M1-<Up>", sendMessage Arrange)
|
||||
, ("M-C-M1-<Down>", sendMessage DeArrange)
|
||||
, ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full
|
||||
, ("M-S-<Space>", sendMessage ToggleStruts) -- Toggles struts
|
||||
, ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder
|
||||
, ("M-<KP_Multiply>", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane
|
||||
, ("M-<KP_Divide>", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane
|
||||
, ("M-S-<KP_Multiply>", increaseLimit) -- Increase number of windows
|
||||
, ("M-S-<KP_Divide>", decreaseLimit) -- Decrease number of windows
|
||||
|
||||
, ("M-h", sendMessage Shrink) -- Shrink horiz window width
|
||||
, ("M-l", sendMessage Expand) -- Expand horiz window width
|
||||
, ("M-C-j", sendMessage MirrorShrink) -- Shrink vert window width
|
||||
, ("M-C-k", sendMessage MirrorExpand) -- Exoand vert window width
|
||||
|
||||
-- Workspaces
|
||||
, ("M-.", nextScreen) -- Switch focus to next monitor
|
||||
, ("M-,", prevScreen) -- Switch focus to prev monitor
|
||||
, ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws
|
||||
, ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws
|
||||
|
||||
-- Scratchpads
|
||||
, ("M-C-<Return>", namedScratchpadAction myScratchPads "terminal")
|
||||
, ("M-C-c", namedScratchpadAction myScratchPads "mocp")
|
||||
|
||||
-- Controls for mocp music player.
|
||||
, ("M-u p", spawn "mocp --play")
|
||||
, ("M-u l", spawn "mocp --next")
|
||||
, ("M-u h", spawn "mocp --previous")
|
||||
, ("M-u <Space>", spawn "mocp --toggle-pause")
|
||||
|
||||
-- Emacs (CTRL-e followed by a key)
|
||||
, ("C-e e", spawn "emacsclient -c -a ''") -- start emacs
|
||||
, ("C-e b", spawn "emacsclient -c -a '' --eval '(ibuffer)'") -- list emacs buffers
|
||||
, ("C-e d", spawn "emacsclient -c -a '' --eval '(dired nil)'") -- dired emacs file manager
|
||||
, ("C-e m", spawn "emacsclient -c -a '' --eval '(mu4e)'") -- mu4e emacs email client
|
||||
, ("C-e n", spawn "emacsclient -c -a '' --eval '(elfeed)'") -- elfeed emacs rss client
|
||||
, ("C-e s", spawn "emacsclient -c -a '' --eval '(eshell)'") -- eshell within emacs
|
||||
, ("C-e t", spawn "emacsclient -c -a '' --eval '(+vterm/here nil)'") -- eshell within emacs
|
||||
-- emms is an emacs audio player. I set it to auto start playing in a specific directory.
|
||||
, ("C-e a", spawn "emacsclient -c -a '' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")
|
||||
|
||||
--- My Applications (Super+Alt+Key)
|
||||
, ("M-M1-a", spawn (myTerminal ++ " -e ncpamixer"))
|
||||
, ("M-M1-b", spawn "surf www.youtube.com/c/DistroTube/")
|
||||
, ("M-M1-e", spawn (myTerminal ++ " -e neomutt"))
|
||||
, ("M-M1-f", spawn (myTerminal ++ " -e sh ./.config/vifm/scripts/vifmrun"))
|
||||
, ("M-M1-i", spawn (myTerminal ++ " -e irssi"))
|
||||
, ("M-M1-j", spawn (myTerminal ++ " -e joplin"))
|
||||
, ("M-M1-l", spawn (myTerminal ++ " -e lynx -cfg=~/.lynx/lynx.cfg -lss=~/.lynx/lynx.lss gopher://distro.tube"))
|
||||
, ("M-M1-m", spawn (myTerminal ++ " -e mocp"))
|
||||
, ("M-M1-n", spawn (myTerminal ++ " -e newsboat"))
|
||||
, ("M-M1-p", spawn (myTerminal ++ " -e pianobar"))
|
||||
, ("M-M1-r", spawn (myTerminal ++ " -e rtv"))
|
||||
, ("M-M1-t", spawn (myTerminal ++ " -e toot curses"))
|
||||
, ("M-M1-w", spawn (myTerminal ++ " -e wopr report.xml"))
|
||||
, ("M-M1-y", spawn (myTerminal ++ " -e youtube-viewer"))
|
||||
|
||||
-- Multimedia Keys
|
||||
, ("<XF86AudioPlay>", spawn "cmus toggle")
|
||||
, ("<XF86AudioPrev>", spawn "cmus prev")
|
||||
, ("<XF86AudioNext>", spawn "cmus next")
|
||||
-- , ("<XF86AudioMute>", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04.
|
||||
, ("<XF86AudioLowerVolume>", spawn "amixer set Master 5%- unmute")
|
||||
, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 5%+ unmute")
|
||||
, ("<XF86HomePage>", spawn "firefox")
|
||||
, ("<XF86Search>", safeSpawn "firefox" ["https://www.google.com/"])
|
||||
, ("<XF86Mail>", runOrRaise "geary" (resource =? "thunderbird"))
|
||||
, ("<XF86Calculator>", runOrRaise "gcalctool" (resource =? "gcalctool"))
|
||||
, ("<XF86Eject>", spawn "toggleeject")
|
||||
, ("<Print>", spawn "scrotd 0")
|
||||
]
|
||||
-- Appending search engine prompts to keybindings list.
|
||||
-- Look at "search engines" section of this config for values for "k".
|
||||
++ [("M-s " ++ k, S.promptSearch dtXPConfig' f) | (k,f) <- searchList ]
|
||||
++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
-- Appending some extra xprompts to keybindings list.
|
||||
-- Look at "xprompt settings" section this of config for values for "k".
|
||||
++ [("M-p " ++ k, f dtXPConfig') | (k,f) <- promptList ]
|
||||
++ [("M-p " ++ k, f dtXPConfig' g) | (k,f,g) <- promptList' ]
|
||||
-- The following lines are needed for named scratchpads.
|
||||
where nonNSP = WSIs (return (\ws -> W.tag ws /= "nsp"))
|
||||
nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "nsp"))
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- MAIN
|
||||
------------------------------------------------------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Launching three instances of xmobar on their monitors.
|
||||
xmproc0 <- spawnPipe "xmobar -x 0 /home/dt/.config/xmobar/xmobarrc0"
|
||||
xmproc1 <- spawnPipe "xmobar -x 1 /home/dt/.config/xmobar/xmobarrc2"
|
||||
xmproc2 <- spawnPipe "xmobar -x 2 /home/dt/.config/xmobar/xmobarrc1"
|
||||
-- the xmonad, ya know...what the WM is named after!
|
||||
xmonad $ ewmh def
|
||||
{ manageHook = ( isFullscreen --> doFullFloat ) <+> myManageHook <+> manageDocks
|
||||
-- Run xmonad commands from command line with "xmonadctl command". Commands include:
|
||||
-- shrink, expand, next-layout, default-layout, restart-wm, xterm, kill, refresh, run,
|
||||
-- focus-up, focus-down, swap-up, swap-down, swap-master, sink, quit-wm. You can run
|
||||
-- "xmonadctl 0" to generate full list of commands written to ~/.xsession-errors.
|
||||
, handleEventHook = serverModeEventHookCmd
|
||||
<+> serverModeEventHook
|
||||
<+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
|
||||
<+> docksEventHook
|
||||
, modMask = myModMask
|
||||
, terminal = myTerminal
|
||||
, startupHook = myStartupHook
|
||||
, layoutHook = showWName' myShowWNameTheme myLayoutHook
|
||||
, workspaces = TS.toWorkspaces myWorkspaces
|
||||
, borderWidth = myBorderWidth
|
||||
, normalBorderColor = myNormColor
|
||||
, focusedBorderColor = myFocusColor
|
||||
, logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP
|
||||
{ ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x
|
||||
, ppCurrent = xmobarColor "#c3e88d" "" . wrap "[" "]" -- Current workspace in xmobar
|
||||
, ppVisible = xmobarColor "#c3e88d" "" -- Visible but not current workspace
|
||||
, ppHidden = xmobarColor "#82AAFF" "" . wrap "*" "" -- Hidden workspaces in xmobar
|
||||
-- , ppHiddenNoWindows = xmobarColor "#F07178" "" -- Hidden workspaces (no windows)
|
||||
, ppHiddenNoWindows= \( _ ) -> "" -- Only shows visible workspaces. Useful for TreeSelect.
|
||||
, ppTitle = xmobarColor "#d0d0d0" "" . shorten 60 -- Title of active window in xmobar
|
||||
, ppSep = "<fc=#666666> | </fc>" -- Separators in xmobar
|
||||
, ppUrgent = xmobarColor "#C45500" "" . wrap "!" "!" -- Urgent workspace
|
||||
, ppExtras = [windowCount] -- # of windows current workspace
|
||||
, ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
|
||||
}
|
||||
} `additionalKeysP` myKeys
|
||||
920
.xmonad/xmonad.hs
Normal file
920
.xmonad/xmonad.hs
Normal file
@@ -0,0 +1,920 @@
|
||||
-- Base
|
||||
import XMonad
|
||||
import System.Directory
|
||||
import System.IO (hPutStrLn)
|
||||
import System.Exit (exitSuccess)
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
-- Actions
|
||||
import XMonad.Actions.CopyWindow (kill1)
|
||||
import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Actions.MouseResize
|
||||
import XMonad.Actions.Promote
|
||||
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
|
||||
import qualified XMonad.Actions.TreeSelect as TS
|
||||
import XMonad.Actions.WindowGo (runOrRaise)
|
||||
import XMonad.Actions.WithAll (sinkAll, killAll)
|
||||
import qualified XMonad.Actions.Search as S
|
||||
|
||||
-- Data
|
||||
import Data.Char (isSpace, toUpper)
|
||||
import Data.Maybe (fromJust)
|
||||
import Data.Monoid
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Tree
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- Hooks
|
||||
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
|
||||
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
|
||||
import XMonad.Hooks.FadeInactive
|
||||
import XMonad.Hooks.ManageDocks (avoidStruts, docksEventHook, manageDocks, ToggleStruts(..))
|
||||
import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat)
|
||||
import XMonad.Hooks.ServerMode
|
||||
import XMonad.Hooks.SetWMName
|
||||
import XMonad.Hooks.WorkspaceHistory
|
||||
|
||||
-- Layouts
|
||||
import XMonad.Layout.GridVariants (Grid(Grid))
|
||||
import XMonad.Layout.SimplestFloat
|
||||
import XMonad.Layout.Spiral
|
||||
import XMonad.Layout.ResizableTile
|
||||
import XMonad.Layout.Tabbed
|
||||
import XMonad.Layout.ThreeColumns
|
||||
|
||||
-- Layouts modifiers
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
|
||||
import XMonad.Layout.Magnifier
|
||||
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
|
||||
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.Renamed
|
||||
import XMonad.Layout.ShowWName
|
||||
import XMonad.Layout.Simplest
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.SubLayouts
|
||||
import XMonad.Layout.WindowNavigation
|
||||
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
|
||||
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
|
||||
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
|
||||
|
||||
-- Prompt
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.Input
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Man
|
||||
import XMonad.Prompt.Pass
|
||||
import XMonad.Prompt.Shell
|
||||
import XMonad.Prompt.Ssh
|
||||
import XMonad.Prompt.Unicode
|
||||
import XMonad.Prompt.XMonad
|
||||
import Control.Arrow (first)
|
||||
|
||||
-- Utilities
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
|
||||
import XMonad.Util.SpawnOnce
|
||||
|
||||
myFont :: String
|
||||
myFont = "xft:SauceCodePro Nerd Font Mono:regular:size=9:antialias=true:hinting=true"
|
||||
|
||||
myEmojiFont :: String
|
||||
myEmojiFont = "xft:JoyPixels:regular:size=9:antialias=true:hinting=true"
|
||||
|
||||
myModMask :: KeyMask
|
||||
myModMask = mod4Mask -- Sets modkey to super/windows key
|
||||
|
||||
myTerminal :: String
|
||||
myTerminal = "alacritty" -- Sets default terminal
|
||||
|
||||
myBrowser :: String
|
||||
myBrowser = "qutebrowser " -- Sets qutebrowser as browser for tree select
|
||||
-- myBrowser = myTerminal ++ " -e lynx " -- Sets lynx as browser for tree select
|
||||
|
||||
myEditor :: String
|
||||
myEditor = "emacsclient -c -a emacs " -- Sets emacs as editor for tree select
|
||||
-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor for tree select
|
||||
|
||||
myBorderWidth :: Dimension
|
||||
myBorderWidth = 2 -- Sets border width for windows
|
||||
|
||||
myNormColor :: String
|
||||
myNormColor = "#282c34" -- Border color of normal windows
|
||||
|
||||
myFocusColor :: String
|
||||
myFocusColor = "#46d9ff" -- Border color of focused windows
|
||||
|
||||
altMask :: KeyMask
|
||||
altMask = mod1Mask -- Setting this for use in xprompts
|
||||
|
||||
windowCount :: X (Maybe String)
|
||||
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
|
||||
|
||||
myStartupHook :: X ()
|
||||
myStartupHook = do
|
||||
spawnOnce "lxsession &"
|
||||
spawnOnce "nitrogen --restore &"
|
||||
spawnOnce "picom --experimental-backends &"
|
||||
spawnOnce "nm-applet &"
|
||||
spawnOnce "volumeicon &"
|
||||
spawnOnce "trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 --tint 0x282c34 --height 22 &"
|
||||
spawnOnce "/usr/bin/emacs --daemon &" -- emacs daemon for the emacsclient
|
||||
-- spawnOnce "kak -d -s mysession &" -- kakoune daemon for better performance
|
||||
-- spawnOnce "urxvtd -q -o -f &" -- urxvt daemon for better performance
|
||||
setWMName "LG3D"
|
||||
|
||||
myColorizer :: Window -> Bool -> X (String, String)
|
||||
myColorizer = colorRangeFromClassName
|
||||
(0x28,0x2c,0x34) -- lowest inactive bg
|
||||
(0x28,0x2c,0x34) -- highest inactive bg
|
||||
(0xc7,0x92,0xea) -- active bg
|
||||
(0xc0,0xa7,0x9a) -- inactive fg
|
||||
(0x28,0x2c,0x34) -- active fg
|
||||
|
||||
-- gridSelect menu layout
|
||||
mygridConfig :: p -> GSConfig Window
|
||||
mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
spawnSelected' :: [(String, String)] -> X ()
|
||||
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
|
||||
where conf = def
|
||||
{ gs_cellheight = 40
|
||||
, gs_cellwidth = 200
|
||||
, gs_cellpadding = 6
|
||||
, gs_originFractX = 0.5
|
||||
, gs_originFractY = 0.5
|
||||
, gs_font = myFont
|
||||
}
|
||||
|
||||
myAppGrid = [ ("Audacity", "audacity")
|
||||
, ("Deadbeef", "deadbeef")
|
||||
, ("Emacs", "emacsclient -c -a emacs")
|
||||
, ("Firefox", "firefox")
|
||||
, ("Geany", "geany")
|
||||
, ("Geary", "geary")
|
||||
, ("Gimp", "gimp")
|
||||
, ("Kdenlive", "kdenlive")
|
||||
, ("LibreOffice Impress", "loimpress")
|
||||
, ("LibreOffice Writer", "lowriter")
|
||||
, ("OBS", "obs")
|
||||
, ("PCManFM", "pcmanfm")
|
||||
]
|
||||
|
||||
treeselectAction :: TS.TSConfig (X ()) -> X ()
|
||||
treeselectAction a = TS.treeselectAction a
|
||||
[ Node (TS.TSNode "+ Accessories" "Accessory applications" (return ()))
|
||||
[ Node (TS.TSNode "Archive Manager" "Tool for archived packages" (spawn "file-roller")) []
|
||||
, Node (TS.TSNode "Calculator" "Gui version of qalc" (spawn "qalculate-gtk")) []
|
||||
, Node (TS.TSNode "Picom Toggle on/off" "Compositor for window managers" (spawn "killall picom; picom --experimental-backend")) []
|
||||
, Node (TS.TSNode "Virt-Manager" "Virtual machine manager" (spawn "virt-manager")) []
|
||||
, Node (TS.TSNode "Virtualbox" "Oracle's virtualization program" (spawn "virtualbox")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Games" "fun and games" (return ()))
|
||||
[ Node (TS.TSNode "0 A.D" "Real-time strategy empire game" (spawn "0ad")) []
|
||||
, Node (TS.TSNode "Battle For Wesnoth" "Turn-based stretegy game" (spawn "wesnoth")) []
|
||||
, Node (TS.TSNode "Steam" "The Steam gaming platform" (spawn "steam")) []
|
||||
, Node (TS.TSNode "SuperTuxKart" "Open source kart racing" (spawn "supertuxkart")) []
|
||||
, Node (TS.TSNode "Xonotic" "Fast-paced first person shooter" (spawn "xonotic")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Graphics" "graphics programs" (return ()))
|
||||
[ Node (TS.TSNode "Gimp" "GNU image manipulation program" (spawn "gimp")) []
|
||||
, Node (TS.TSNode "Inkscape" "An SVG editing program" (spawn "inkscape")) []
|
||||
, Node (TS.TSNode "LibreOffice Draw" "LibreOffice drawing program" (spawn "lodraw")) []
|
||||
, Node (TS.TSNode "Shotwell" "Photo management program" (spawn "shotwell")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Internet" "internet and web programs" (return ()))
|
||||
[ Node (TS.TSNode "Brave" "A privacy-oriented web browser" (spawn "brave")) []
|
||||
, Node (TS.TSNode "Discord" "Chat and video chat platform" (spawn "discord")) []
|
||||
, Node (TS.TSNode "Elfeed" "An Emacs RSS feed reader" (spawn "emacsclient -c -a '' --eval '(elfeed)'")) []
|
||||
, Node (TS.TSNode "Firefox" "Open source web browser" (spawn "firefox")) []
|
||||
, Node (TS.TSNode "Mastodon" "An Emacs mastodon client" (spawn "emacsclient -c -a '' --eval '(mastodon)'")) []
|
||||
, Node (TS.TSNode "Mu4e" "An Emacs email client" (spawn "emacsclient -c -a '' --eval '(mu4e)'")) []
|
||||
, Node (TS.TSNode "Nextcloud" "File syncing desktop utility" (spawn "nextcloud")) []
|
||||
, Node (TS.TSNode "Qutebrowser" "Minimal web browser" (spawn "qutebrowser")) []
|
||||
, Node (TS.TSNode "Surf Browser" "Suckless surf web browser" (spawn "surf")) []
|
||||
, Node (TS.TSNode "Thunderbird" "Open source email client" (spawn "thunderbird")) []
|
||||
, Node (TS.TSNode "Transmission" "Bittorrent client" (spawn "transmission-gtk")) []
|
||||
, Node (TS.TSNode "Zoom" "Web conferencing" (spawn "zoom")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Multimedia" "sound and video applications" (return ()))
|
||||
[ Node (TS.TSNode "Alsa Mixer" "Alsa volume control utility" (spawn (myTerminal ++ " -e alsamixer"))) []
|
||||
, Node (TS.TSNode "Audacity" "Graphical audio editing program" (spawn "audacity")) []
|
||||
, Node (TS.TSNode "Deadbeef" "Lightweight music player" (spawn "deadbeef")) []
|
||||
, Node (TS.TSNode "EMMS" "Emacs multimedia player" (spawn "xxx")) []
|
||||
, Node (TS.TSNode "Kdenlive" "Open source non-linear video editor" (spawn "kdenlive")) []
|
||||
, Node (TS.TSNode "OBS Studio" "Open Broadcaster Software" (spawn "obs")) []
|
||||
, Node (TS.TSNode "Pianobar" "A terminal Pandora client" (spawn (myTerminal ++ " -e pianobar"))) []
|
||||
, Node (TS.TSNode "VLC" "Multimedia player and server" (spawn "vlc")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Office" "office applications" (return ()))
|
||||
[ Node (TS.TSNode "LibreOffice" "Open source office suite" (spawn "libreoffice")) []
|
||||
, Node (TS.TSNode "LibreOffice Base" "Desktop database front end" (spawn "lobase")) []
|
||||
, Node (TS.TSNode "LibreOffice Calc" "Spreadsheet program" (spawn "localc")) []
|
||||
, Node (TS.TSNode "LibreOffice Draw" "Diagrams and sketches" (spawn "lodraw")) []
|
||||
, Node (TS.TSNode "LibreOffice Impress" "Presentation program" (spawn "loimpress")) []
|
||||
, Node (TS.TSNode "LibreOffice Math" "Formula editor" (spawn "lomath")) []
|
||||
, Node (TS.TSNode "LibreOffice Writer" "Word processor" (spawn "lowriter")) []
|
||||
, Node (TS.TSNode "Zathura" "PDF Viewer" (spawn "zathura")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Programming" "programming and scripting tools" (return ()))
|
||||
[ Node (TS.TSNode "+ Emacs" "Emacs is more than a text editor" (return ()))
|
||||
[ Node (TS.TSNode "Emacs Client" "Doom Emacs launched as client" (spawn "emacsclient -c -a emacs")) []
|
||||
, Node (TS.TSNode "M-x dired" "File manager for Emacs" (spawn "emacsclient -c -a '' --eval '(dired nil)'")) []
|
||||
, Node (TS.TSNode "M-x elfeed" "RSS client for Emacs" (spawn "emacsclient -c -a '' --eval '(elfeed)'")) []
|
||||
, Node (TS.TSNode "M-x emms" "Emacs" (spawn "emacsclient -c -a '' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")) []
|
||||
, Node (TS.TSNode "M-x erc" "IRC client for Emacs" (spawn "emacsclient -c -a '' --eval '(erc)'")) []
|
||||
, Node (TS.TSNode "M-x eshell" "The Eshell in Emacs" (spawn "emacsclient -c -a '' --eval '(eshell)'")) []
|
||||
, Node (TS.TSNode "M-x ibuffer" "Emacs buffer list" (spawn "emacsclient -c -a '' --eval '(ibuffer)'")) []
|
||||
, Node (TS.TSNode "M-x mastodon" "Emacs" (spawn "emacsclient -c -a '' --eval '(mastodon)'")) []
|
||||
, Node (TS.TSNode "M-x mu4e" "Email client for Emacs" (spawn "emacsclient -c -a '' --eval '(mu4e)'")) []
|
||||
, Node (TS.TSNode "M-x vterm" "Emacs" (spawn "emacsclient -c -a '' --eval '(+vterm/here nil))'")) []
|
||||
]
|
||||
, Node (TS.TSNode "Python" "Python interactive prompt" (spawn (myTerminal ++ " -e python"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ System" "system tools and utilities" (return ()))
|
||||
[ Node (TS.TSNode "Alacritty" "GPU accelerated terminal" (spawn "alacritty")) []
|
||||
, Node (TS.TSNode "Dired" "File manager for Emacs" (spawn "emacsclient -c -a '' --eval '(dired nil)'")) []
|
||||
, Node (TS.TSNode "Eshell" "The eshell in Emacs" (spawn "emacsclient -c -a '' --eval '(eshell)'")) []
|
||||
, Node (TS.TSNode "Gufw" "GUI uncomplicated firewall" (spawn "gufw")) []
|
||||
, Node (TS.TSNode "Htop" "Terminal process viewer" (spawn (myTerminal ++ " -e htop"))) []
|
||||
, Node (TS.TSNode "LXAppearance" "Customize look and feel; set GTK theme" (spawn "lxappearance")) []
|
||||
, Node (TS.TSNode "Nitrogen" "Wallpaper viewer and setter" (spawn "nitrogen")) []
|
||||
, Node (TS.TSNode "PCManFM" "Lightweight graphical file manager" (spawn "pcmanfm")) []
|
||||
, Node (TS.TSNode "Qt5ct" "Change your Qt theme" (spawn "qt5ct")) []
|
||||
, Node (TS.TSNode "Simple Terminal" "Suckless simple terminal" (spawn "st")) []
|
||||
, Node (TS.TSNode "Stress Terminal UI" "Stress your system" (spawn (myTerminal ++ " -e s-tui"))) []
|
||||
]
|
||||
, Node (TS.TSNode "------------------------" "" (spawn "xdotool key Escape")) []
|
||||
, Node (TS.TSNode "+ Bookmarks" "a list of web bookmarks" (return ()))
|
||||
[ Node (TS.TSNode "+ Linux" "a list of web bookmarks" (return ()))
|
||||
[ Node (TS.TSNode "+ Arch Linux" "btw, i use arch!" (return ()))
|
||||
[ Node (TS.TSNode "Arch Linux" "Arch Linux homepage" (spawn (myBrowser ++ "https://www.archlinux.org/"))) []
|
||||
, Node (TS.TSNode "Arch Wiki" "The best Linux wiki" (spawn (myBrowser ++ "https://wiki.archlinux.org/"))) []
|
||||
, Node (TS.TSNode "AUR" "Arch User Repository" (spawn (myBrowser ++ "https://aur.archlinux.org/"))) []
|
||||
, Node (TS.TSNode "Arch Forums" "Arch Linux web forum" (spawn (myBrowser ++ "https://bbs.archlinux.org/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Linux News" "linux news and blogs" (return ()))
|
||||
[ Node (TS.TSNode "DistroWatch" "Linux distro release announcments" (spawn (myBrowser ++ "https://distrowatch.com/"))) []
|
||||
, Node (TS.TSNode "LXer" "LXer linux news aggregation" (spawn (myBrowser ++ "http://lxer.com"))) []
|
||||
, Node (TS.TSNode "OMG Ubuntu" "Ubuntu news, apps and reviews" (spawn (myBrowser ++ "https://www.omgubuntu.co.uk"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Window Managers" "window manager documentation" (return ()))
|
||||
[ Node (TS.TSNode "+ XMonad" "xmonad documentation" (return ()))
|
||||
[ Node (TS.TSNode "XMonad" "Homepage for XMonad" (spawn (myBrowser ++ "http://xmonad.org"))) []
|
||||
, Node (TS.TSNode "XMonad GitHub" "The GitHub page for XMonad" (spawn (myBrowser ++ "https://github.com/xmonad/xmonad"))) []
|
||||
, Node (TS.TSNode "xmonad-contrib" "Third party extensions for XMonad" (spawn (myBrowser ++ "https://hackage.haskell.org/package/xmonad-contrib"))) []
|
||||
, Node (TS.TSNode "xmonad-ontrib GitHub" "The GitHub page for xmonad-contrib" (spawn (myBrowser ++ "https://github.com/xmonad/xmonad-contrib"))) []
|
||||
, Node (TS.TSNode "Xmobar" "Minimal text-based status bar" (spawn (myBrowser ++ "https://hackage.haskell.org/package/xmobar"))) []
|
||||
]
|
||||
]
|
||||
]
|
||||
, Node (TS.TSNode "+ Emacs" "Emacs documentation" (return ()))
|
||||
[ Node (TS.TSNode "GNU Emacs" "Extensible free/libre text editor" (spawn (myBrowser ++ "https://www.gnu.org/software/emacs/"))) []
|
||||
, Node (TS.TSNode "Doom Emacs" "Emacs distribution with sane defaults" (spawn (myBrowser ++ "https://github.com/hlissner/doom-emacs"))) []
|
||||
, Node (TS.TSNode "r/emacs" "M-x emacs-reddit" (spawn (myBrowser ++ "https://www.reddit.com/r/emacs/"))) []
|
||||
, Node (TS.TSNode "EmacsWiki" "EmacsWiki Site Map" (spawn (myBrowser ++ "https://www.emacswiki.org/emacs/SiteMap"))) []
|
||||
, Node (TS.TSNode "Emacs StackExchange" "Q&A site for emacs" (spawn (myBrowser ++ "https://emacs.stackexchange.com/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Search and Reference" "Search engines, indices and wikis" (return ()))
|
||||
[ Node (TS.TSNode "DuckDuckGo" "Privacy-oriented search engine" (spawn (myBrowser ++ "https://duckduckgo.com/"))) []
|
||||
, Node (TS.TSNode "Google" "The evil search engine" (spawn (myBrowser ++ "http://www.google.com"))) []
|
||||
, Node (TS.TSNode "Thesaurus" "Lookup synonyms and antonyms" (spawn (myBrowser ++ "https://www.thesaurus.com/"))) []
|
||||
, Node (TS.TSNode "Wikipedia" "The free encyclopedia" (spawn (myBrowser ++ "https://www.wikipedia.org/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Programming" "programming and scripting" (return ()))
|
||||
[ Node (TS.TSNode "+ Bash and Shell Scripting" "shell scripting documentation" (return ()))
|
||||
[ Node (TS.TSNode "GNU Bash" "Documentation for bash" (spawn (myBrowser ++ "https://www.gnu.org/software/bash/manual/"))) []
|
||||
, Node (TS.TSNode "r/bash" "Subreddit for bash" (spawn (myBrowser ++ "https://www.reddit.com/r/bash/"))) []
|
||||
, Node (TS.TSNode "r/commandline" "Subreddit for the command line" (spawn (myBrowser ++ "https://www.reddit.com/r/commandline/"))) []
|
||||
, Node (TS.TSNode "Learn Shell" "Interactive shell tutorial" (spawn (myBrowser ++ "https://www.learnshell.org/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Elisp" "emacs lisp documentation" (return ()))
|
||||
[ Node (TS.TSNode "Emacs Lisp" "Reference manual for elisp" (spawn (myBrowser ++ "https://www.gnu.org/software/emacs/manual/html_node/elisp/"))) []
|
||||
, Node (TS.TSNode "Learn Elisp in Y Minutes" "Single webpage for elisp basics" (spawn (myBrowser ++ "https://learnxinyminutes.com/docs/elisp/"))) []
|
||||
, Node (TS.TSNode "r/Lisp" "Subreddit for lisp languages" (spawn (myBrowser ++ "https://www.reddit.com/r/lisp/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Haskell" "haskell documentation" (return ()))
|
||||
[ Node (TS.TSNode "Haskell.org" "Homepage for haskell" (spawn (myBrowser ++ "http://www.haskell.org"))) []
|
||||
, Node (TS.TSNode "Hoogle" "Haskell API search engine" (spawn "https://hoogle.haskell.org/")) []
|
||||
, Node (TS.TSNode "r/haskell" "Subreddit for haskell" (spawn (myBrowser ++ "https://www.reddit.com/r/Python/"))) []
|
||||
, Node (TS.TSNode "Haskell on StackExchange" "Newest haskell topics on StackExchange" (spawn (myBrowser ++ "https://stackoverflow.com/questions/tagged/haskell"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Python" "python documentation" (return ()))
|
||||
[ Node (TS.TSNode "Python.org" "Homepage for python" (spawn (myBrowser ++ "https://www.python.org/"))) []
|
||||
, Node (TS.TSNode "r/Python" "Subreddit for python" (spawn (myBrowser ++ "https://www.reddit.com/r/Python/"))) []
|
||||
, Node (TS.TSNode "Python on StackExchange" "Newest python topics on StackExchange" (spawn (myBrowser ++ "https://stackoverflow.com/questions/tagged/python"))) []
|
||||
]
|
||||
]
|
||||
, Node (TS.TSNode "+ Vim" "vim and neovim documentation" (return ()))
|
||||
[ Node (TS.TSNode "Vim.org" "Vim, the ubiquitous text editor" (spawn (myBrowser ++ "https://www.vim.org/"))) []
|
||||
, Node (TS.TSNode "r/Vim" "Subreddit for vim" (spawn (myBrowser ++ "https://www.reddit.com/r/vim/"))) []
|
||||
, Node (TS.TSNode "Vi/m StackExchange" "Vi/m related questions" (spawn (myBrowser ++ "https://vi.stackexchange.com/"))) []
|
||||
]
|
||||
, Node (TS.TSNode "My Start Page" "Custom start page for browser" (spawn (myBrowser ++ "file://$HOME/.surf/html/homepage.html"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Config Files" "config files that edit often" (return ()))
|
||||
[ Node (TS.TSNode "+ doom emacs configs" "My doom emacs config files" (return ()))
|
||||
[ Node (TS.TSNode "Doom Emacs config.org" "doom emacs config" (spawn (myEditor ++ "$HOME/.doom.d/config.org"))) []
|
||||
, Node (TS.TSNode "Doom Emacs init.el" "doom emacs init" (spawn (myEditor ++ "$HOME/.doom.d/init.el"))) []
|
||||
, Node (TS.TSNode "Doom Emacs packages.el" "doom emacs packages" (spawn (myEditor ++ "$HOME/.doom.d/packages.el"))) []
|
||||
, Node (TS.TSNode "Doom Emacs eshell aliases" "the aliases for use in eshell" (spawn (myEditor ++ "$HOME/.doom.d/aliases"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ xmobar configs" "My xmobar config files" (return ()))
|
||||
[ Node (TS.TSNode "xmobar mon1" "status bar on monitor 1" (spawn (myEditor ++ "$HOME/.config/xmobar/xmobarrc0"))) []
|
||||
, Node (TS.TSNode "xmobar mon2" "status bar on monitor 2" (spawn (myEditor ++ "$HOME/.config/xmobar/xmobarrc2"))) []
|
||||
, Node (TS.TSNode "xmobar mon3" "status bar on monitor 3" (spawn (myEditor ++ "$HOME/.config/xmobar/xmobarrc1"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ xmonad configs" "My xmonad config files" (return ()))
|
||||
[ Node (TS.TSNode "xmonad.hs" "My XMonad Main" (spawn (myEditor ++ "$HOME/.xmonad/xmonad.hs"))) []
|
||||
, Node (TS.TSNode "xmonadctl.hs" "The xmonadctl script" (spawn (myEditor ++ "$HOME/.xmonad/xmonadctl.hs"))) []
|
||||
]
|
||||
, Node (TS.TSNode "alacritty" "alacritty terminal emulator" (spawn (myEditor ++ "$HOME/.config/alacritty/alacritty.yml"))) []
|
||||
, Node (TS.TSNode "bashrc" "the bourne again shell" (spawn (myEditor ++ "$HOME/.bashrc"))) []
|
||||
, Node (TS.TSNode "dunst" "dunst notifications" (spawn (myEditor ++ "$HOME/.config/dunst/dunstrc"))) []
|
||||
, Node (TS.TSNode "fishrc" "the friendly interactive shell" (spawn (myEditor ++ "$HOME/.config/fish/config.fish"))) []
|
||||
, Node (TS.TSNode "neovim init.vim" "neovim text editor" (spawn (myEditor ++ "$HOME/.config/nvim/init.vim"))) []
|
||||
, Node (TS.TSNode "qutebrowser config.py" "qutebrowser web browser" (spawn (myEditor ++ "$HOME/.config/qutebrowser/config.py"))) []
|
||||
, Node (TS.TSNode "xresources" "xresources file" (spawn (myEditor ++ "$HOME/.Xresources"))) []
|
||||
, Node (TS.TSNode "zshrc" "Config for the z shell" (spawn (myEditor ++ "$HOME/.zshrc"))) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Screenshots" "take a screenshot" (return ()))
|
||||
[ Node (TS.TSNode "Quick fullscreen" "take screenshot immediately" (spawn "scrot -d 1 ~/scrot/%Y-%m-%d-@%H-%M-%S-scrot.png")) []
|
||||
, Node (TS.TSNode "Delayed fullscreen" "take screenshot in 5 secs" (spawn "scrot -d 5 ~/scrot/%Y-%m-%d-@%H-%M-%S-scrot.png")) []
|
||||
, Node (TS.TSNode "Section screenshot" "take screenshot of section" (spawn "scrot -s ~/scrot/%Y-%m-%d-@%H-%M-%S-scrot.png")) []
|
||||
]
|
||||
, Node (TS.TSNode "------------------------" "" (spawn "xdotool key Escape")) [] , Node (TS.TSNode "+ Get Help For..." "useful sites and videos for help" (return ()))
|
||||
[ Node (TS.TSNode "+ Alacritty" "information about alacritty terminal" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 1")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 3")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Bash" "information about bash and scripting" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Emacs Lisp" "information about elisp programming" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Fish" "information about fish shell" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Haskell" "information about haskell programming" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Python" "information about python programming" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Qutebrowser" "information about qutebrowser" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ XMonad" "information about xmonad" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
]
|
||||
]
|
||||
, Node (TS.TSNode "------------------------" "" (spawn "xdotool key Escape")) []
|
||||
, Node (TS.TSNode "+ XMonad Controls" "window manager commands" (return ()))
|
||||
[ Node (TS.TSNode "+ View Workspaces" "View a specific workspace" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 1")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 3")) []
|
||||
, Node (TS.TSNode "View 3" "View workspace 3" (spawn "~/.xmonad/xmonadctl 5")) []
|
||||
, Node (TS.TSNode "View 4" "View workspace 4" (spawn "~/.xmonad/xmonadctl 7")) []
|
||||
, Node (TS.TSNode "View 5" "View workspace 5" (spawn "~/.xmonad/xmonadctl 9")) []
|
||||
, Node (TS.TSNode "View 6" "View workspace 6" (spawn "~/.xmonad/xmonadctl 11")) []
|
||||
, Node (TS.TSNode "View 7" "View workspace 7" (spawn "~/.xmonad/xmonadctl 13")) []
|
||||
, Node (TS.TSNode "View 8" "View workspace 8" (spawn "~/.xmonad/xmonadctl 15")) []
|
||||
, Node (TS.TSNode "View 9" "View workspace 9" (spawn "~/.xmonad/xmonadctl 17")) []
|
||||
]
|
||||
, Node (TS.TSNode "+ Shift Workspaces" "Send focused window to specific workspace" (return ()))
|
||||
[ Node (TS.TSNode "View 1" "View workspace 1" (spawn "~/.xmonad/xmonadctl 2")) []
|
||||
, Node (TS.TSNode "View 2" "View workspace 2" (spawn "~/.xmonad/xmonadctl 4")) []
|
||||
, Node (TS.TSNode "View 3" "View workspace 3" (spawn "~/.xmonad/xmonadctl 6")) []
|
||||
, Node (TS.TSNode "View 4" "View workspace 4" (spawn "~/.xmonad/xmonadctl 8")) []
|
||||
, Node (TS.TSNode "View 5" "View workspace 5" (spawn "~/.xmonad/xmonadctl 10")) []
|
||||
, Node (TS.TSNode "View 6" "View workspace 6" (spawn "~/.xmonad/xmonadctl 12")) []
|
||||
, Node (TS.TSNode "View 7" "View workspace 7" (spawn "~/.xmonad/xmonadctl 14")) []
|
||||
, Node (TS.TSNode "View 8" "View workspace 8" (spawn "~/.xmonad/xmonadctl 16")) []
|
||||
, Node (TS.TSNode "View 9" "View workspace 9" (spawn "~/.xmonad/xmonadctl 18")) []
|
||||
]
|
||||
, Node (TS.TSNode "Next layout" "Switch to next layout" (spawn "~/.xmonad/xmonadctl next-layout")) []
|
||||
, Node (TS.TSNode "Recompile" "Recompile XMonad" (spawn "xmonad --recompile")) []
|
||||
, Node (TS.TSNode "Restart" "Restart XMonad" (spawn "xmonad --restart")) []
|
||||
, Node (TS.TSNode "Quit" "Restart XMonad" (io exitSuccess)) []
|
||||
]
|
||||
]
|
||||
|
||||
tsDefaultConfig :: TS.TSConfig a
|
||||
tsDefaultConfig = TS.TSConfig { TS.ts_hidechildren = True
|
||||
, TS.ts_background = 0xdd282c34
|
||||
, TS.ts_font = myFont
|
||||
, TS.ts_node = (0xffd0d0d0, 0xff1c1f24)
|
||||
, TS.ts_nodealt = (0xffd0d0d0, 0xff282c34)
|
||||
, TS.ts_highlight = (0xffffffff, 0xff755999)
|
||||
, TS.ts_extra = 0xffd0d0d0
|
||||
, TS.ts_node_width = 200
|
||||
, TS.ts_node_height = 20
|
||||
, TS.ts_originX = 100
|
||||
, TS.ts_originY = 100
|
||||
, TS.ts_indent = 80
|
||||
, TS.ts_navigate = myTreeNavigation
|
||||
}
|
||||
|
||||
myTreeNavigation = M.fromList
|
||||
[ ((0, xK_Escape), TS.cancel)
|
||||
, ((0, xK_Return), TS.select)
|
||||
, ((0, xK_space), TS.select)
|
||||
, ((0, xK_Up), TS.movePrev)
|
||||
, ((0, xK_Down), TS.moveNext)
|
||||
, ((0, xK_Left), TS.moveParent)
|
||||
, ((0, xK_Right), TS.moveChild)
|
||||
, ((0, xK_k), TS.movePrev)
|
||||
, ((0, xK_j), TS.moveNext)
|
||||
, ((0, xK_h), TS.moveParent)
|
||||
, ((0, xK_l), TS.moveChild)
|
||||
, ((0, xK_o), TS.moveHistBack)
|
||||
, ((0, xK_i), TS.moveHistForward)
|
||||
, ((0, xK_a), TS.moveTo ["+ Accessories"])
|
||||
, ((0, xK_e), TS.moveTo ["+ Games"])
|
||||
, ((0, xK_g), TS.moveTo ["+ Graphics"])
|
||||
, ((0, xK_i), TS.moveTo ["+ Internet"])
|
||||
, ((0, xK_m), TS.moveTo ["+ Multimedia"])
|
||||
, ((0, xK_o), TS.moveTo ["+ Office"])
|
||||
, ((0, xK_p), TS.moveTo ["+ Programming"])
|
||||
, ((0, xK_s), TS.moveTo ["+ System"])
|
||||
, ((0, xK_b), TS.moveTo ["+ Bookmarks"])
|
||||
, ((0, xK_c), TS.moveTo ["+ Config Files"])
|
||||
, ((0, xK_r), TS.moveTo ["+ Screenshots"])
|
||||
, ((mod4Mask, xK_l), TS.moveTo ["+ Bookmarks", "+ Linux"])
|
||||
, ((mod4Mask, xK_e), TS.moveTo ["+ Bookmarks", "+ Emacs"])
|
||||
, ((mod4Mask, xK_s), TS.moveTo ["+ Bookmarks", "+ Search and Reference"])
|
||||
, ((mod4Mask, xK_p), TS.moveTo ["+ Bookmarks", "+ Programming"])
|
||||
, ((mod4Mask, xK_v), TS.moveTo ["+ Bookmarks", "+ Vim"])
|
||||
, ((mod4Mask .|. altMask, xK_a), TS.moveTo ["+ Bookmarks", "+ Linux", "+ Arch Linux"])
|
||||
, ((mod4Mask .|. altMask, xK_n), TS.moveTo ["+ Bookmarks", "+ Linux", "+ Linux News"])
|
||||
, ((mod4Mask .|. altMask, xK_w), TS.moveTo ["+ Bookmarks", "+ Linux", "+ Window Managers"])
|
||||
]
|
||||
|
||||
dtXPConfig :: XPConfig
|
||||
dtXPConfig = def
|
||||
{ font = myFont
|
||||
, bgColor = "#282c34"
|
||||
, fgColor = "#bbc2cf"
|
||||
, bgHLight = "#c792ea"
|
||||
, fgHLight = "#000000"
|
||||
, borderColor = "#535974"
|
||||
, promptBorderWidth = 0
|
||||
, promptKeymap = dtXPKeymap
|
||||
, position = Top
|
||||
-- , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.3 }
|
||||
, height = 23
|
||||
, historySize = 256
|
||||
, historyFilter = id
|
||||
, defaultText = []
|
||||
, autoComplete = Just 100000 -- set Just 100000 for .1 sec
|
||||
, showCompletionOnTab = False
|
||||
-- , searchPredicate = isPrefixOf
|
||||
, searchPredicate = fuzzyMatch
|
||||
, defaultPrompter = id $ map toUpper -- change prompt to UPPER
|
||||
-- , defaultPrompter = unwords . map reverse . words -- reverse the prompt
|
||||
-- , defaultPrompter = drop 5 .id (++ "XXXX: ") -- drop first 5 chars of prompt and add XXXX:
|
||||
, alwaysHighlight = True
|
||||
, maxComplRows = Nothing -- set to 'Just 5' for 5 rows
|
||||
}
|
||||
|
||||
-- The same config above minus the autocomplete feature which is annoying
|
||||
-- on certain Xprompts, like the search engine prompts.
|
||||
dtXPConfig' :: XPConfig
|
||||
dtXPConfig' = dtXPConfig
|
||||
{ autoComplete = Nothing
|
||||
}
|
||||
|
||||
emojiXPConfig :: XPConfig
|
||||
emojiXPConfig = dtXPConfig
|
||||
{ font = myEmojiFont
|
||||
}
|
||||
|
||||
calcPrompt c ans =
|
||||
inputPrompt c (trim ans) ?+ \input ->
|
||||
liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c
|
||||
where
|
||||
trim = f . f
|
||||
where f = reverse . dropWhile isSpace
|
||||
|
||||
dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ())
|
||||
dtXPKeymap = M.fromList $
|
||||
map (first $ (,) controlMask) -- control + <key>
|
||||
[ (xK_z, killBefore) -- kill line backwards
|
||||
, (xK_k, killAfter) -- kill line forwards
|
||||
, (xK_a, startOfLine) -- move to the beginning of the line
|
||||
, (xK_e, endOfLine) -- move to the end of the line
|
||||
, (xK_m, deleteString Next) -- delete a character foward
|
||||
, (xK_b, moveCursor Prev) -- move cursor forward
|
||||
, (xK_f, moveCursor Next) -- move cursor backward
|
||||
, (xK_BackSpace, killWord Prev) -- kill the previous word
|
||||
, (xK_y, pasteString) -- paste a string
|
||||
, (xK_g, quit) -- quit out of prompt
|
||||
, (xK_bracketleft, quit)
|
||||
]
|
||||
++
|
||||
map (first $ (,) altMask) -- meta key + <key>
|
||||
[ (xK_BackSpace, killWord Prev) -- kill the prev word
|
||||
, (xK_f, moveWord Next) -- move a word forward
|
||||
, (xK_b, moveWord Prev) -- move a word backward
|
||||
, (xK_d, killWord Next) -- kill the next word
|
||||
, (xK_n, moveHistory W.focusUp') -- move up thru history
|
||||
, (xK_p, moveHistory W.focusDown') -- move down thru history
|
||||
]
|
||||
++
|
||||
map (first $ (,) 0) -- <key>
|
||||
[ (xK_Return, setSuccess True >> setDone True)
|
||||
, (xK_KP_Enter, setSuccess True >> setDone True)
|
||||
, (xK_BackSpace, deleteString Prev)
|
||||
, (xK_Delete, deleteString Next)
|
||||
, (xK_Left, moveCursor Prev)
|
||||
, (xK_Right, moveCursor Next)
|
||||
, (xK_Home, startOfLine)
|
||||
, (xK_End, endOfLine)
|
||||
, (xK_Down, moveHistory W.focusUp')
|
||||
, (xK_Up, moveHistory W.focusDown')
|
||||
, (xK_Escape, quit)
|
||||
]
|
||||
|
||||
archwiki, ebay, news, reddit, urban, yacy :: S.SearchEngine
|
||||
|
||||
archwiki = S.searchEngine "archwiki" "https://wiki.archlinux.org/index.php?search="
|
||||
ebay = S.searchEngine "ebay" "https://www.ebay.com/sch/i.html?_nkw="
|
||||
news = S.searchEngine "news" "https://news.google.com/search?q="
|
||||
reddit = S.searchEngine "reddit" "https://www.reddit.com/search/?q="
|
||||
urban = S.searchEngine "urban" "https://www.urbandictionary.com/define.php?term="
|
||||
yacy = S.searchEngine "yacy" "http://localhost:8090/yacysearch.html?query="
|
||||
|
||||
-- This is the list of search engines that I want to use. Some are from
|
||||
-- XMonad.Actions.Search, and some are the ones that I added above.
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("a", archwiki)
|
||||
, ("d", S.duckduckgo)
|
||||
, ("e", ebay)
|
||||
, ("g", S.google)
|
||||
, ("h", S.hoogle)
|
||||
, ("i", S.images)
|
||||
, ("n", news)
|
||||
, ("r", reddit)
|
||||
, ("s", S.stackage)
|
||||
, ("t", S.thesaurus)
|
||||
, ("v", S.vocabulary)
|
||||
, ("b", S.wayback)
|
||||
, ("u", urban)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("S-y", yacy)
|
||||
, ("z", S.amazon)
|
||||
]
|
||||
|
||||
myScratchPads :: [NamedScratchpad]
|
||||
myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
|
||||
, NS "mocp" spawnMocp findMocp manageMocp
|
||||
]
|
||||
where
|
||||
spawnTerm = myTerminal ++ " -n scratchpad"
|
||||
findTerm = resource =? "scratchpad"
|
||||
manageTerm = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
spawnMocp = myTerminal ++ " -n mocp 'mocp'"
|
||||
findMocp = resource =? "mocp"
|
||||
manageMocp = customFloating $ W.RationalRect l t w h
|
||||
where
|
||||
h = 0.9
|
||||
w = 0.9
|
||||
t = 0.95 -h
|
||||
l = 0.95 -w
|
||||
|
||||
--Makes setting the spacingRaw simpler to write. The spacingRaw module adds a configurable amount of space around windows.
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
|
||||
|
||||
-- Below is a variation of the above except no borders are applied
|
||||
-- if fewer than two windows. So a single window has no gaps.
|
||||
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
|
||||
|
||||
-- Defining a bunch of layouts, many that I don't use.
|
||||
-- limitWindows n sets maximum number of windows displayed for layout.
|
||||
-- mySpacing n sets the gap size around the windows.
|
||||
tall = renamed [Replace "tall"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
magnify = renamed [Replace "magnify"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ magnifier
|
||||
$ limitWindows 12
|
||||
$ mySpacing 8
|
||||
$ ResizableTall 1 (3/100) (1/2) []
|
||||
monocle = renamed [Replace "monocle"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 20 Full
|
||||
floats = renamed [Replace "floats"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 20 simplestFloat
|
||||
grid = renamed [Replace "grid"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 12
|
||||
$ mySpacing 0
|
||||
$ mkToggle (single MIRROR)
|
||||
$ Grid (16/10)
|
||||
spirals = renamed [Replace "spirals"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ mySpacing' 8
|
||||
$ spiral (6/7)
|
||||
threeCol = renamed [Replace "threeCol"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 7
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
threeRow = renamed [Replace "threeRow"]
|
||||
$ windowNavigation
|
||||
$ addTabs shrinkText myTabTheme
|
||||
$ subLayout [] (smartBorders Simplest)
|
||||
$ limitWindows 7
|
||||
-- Mirror takes a layout and rotates it by 90 degrees.
|
||||
-- So we are applying Mirror to the ThreeCol layout.
|
||||
$ Mirror
|
||||
$ ThreeCol 1 (3/100) (1/2)
|
||||
tabs = renamed [Replace "tabs"]
|
||||
-- I cannot add spacing to this layout because it will
|
||||
-- add spacing between window and tabs which looks bad.
|
||||
$ tabbed shrinkText myTabTheme
|
||||
|
||||
-- setting colors for tabs layout and tabs sublayout.
|
||||
myTabTheme = def { fontName = myFont
|
||||
, activeColor = "#46d9ff"
|
||||
, inactiveColor = "#313846"
|
||||
, activeBorderColor = "#46d9ff"
|
||||
, inactiveBorderColor = "#282c34"
|
||||
, activeTextColor = "#282c34"
|
||||
, inactiveTextColor = "#d0d0d0"
|
||||
}
|
||||
|
||||
-- Theme for showWName which prints current workspace when you change workspaces.
|
||||
myShowWNameTheme :: SWNConfig
|
||||
myShowWNameTheme = def
|
||||
{ swn_font = "xft:Ubuntu:bold:size=60"
|
||||
, swn_fade = 1.0
|
||||
, swn_bgcolor = "#1c1f24"
|
||||
, swn_color = "#ffffff"
|
||||
}
|
||||
|
||||
-- The layout hook
|
||||
myLayoutHook = avoidStruts $ mouseResize $ windowArrange $ T.toggleLayouts floats
|
||||
$ mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
|
||||
where
|
||||
myDefaultLayout = tall
|
||||
||| magnify
|
||||
||| noBorders monocle
|
||||
||| floats
|
||||
||| noBorders tabs
|
||||
||| grid
|
||||
||| spirals
|
||||
||| threeCol
|
||||
||| threeRow
|
||||
|
||||
-- myWorkspaces = [" 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 "]
|
||||
myWorkspaces = [" dev ", " www ", " sys ", " doc ", " vbox ", " chat ", " mus ", " vid ", " gfx "]
|
||||
myWorkspaceIndices = M.fromList $ zipWith (,) myWorkspaces [1..] -- (,) == \x y -> (x,y)
|
||||
|
||||
clickable ws = "<action=xdotool key super+"++show i++">"++ws++"</action>"
|
||||
where i = fromJust $ M.lookup ws myWorkspaceIndices
|
||||
|
||||
myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
|
||||
myManageHook = composeAll
|
||||
-- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
|
||||
-- I'm doing it this way because otherwise I would have to write out the full
|
||||
-- name of my workspaces, and the names would very long if using clickable workspaces.
|
||||
[ title =? "Mozilla Firefox" --> doShift ( myWorkspaces !! 1 )
|
||||
, className =? "mpv" --> doShift ( myWorkspaces !! 7 )
|
||||
, className =? "Gimp" --> doShift ( myWorkspaces !! 8 )
|
||||
, className =? "Gimp" --> doFloat
|
||||
, title =? "Oracle VM VirtualBox Manager" --> doFloat
|
||||
, className =? "VirtualBox Manager" --> doShift ( myWorkspaces !! 4 )
|
||||
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
|
||||
] <+> namedScratchpadManageHook myScratchPads
|
||||
|
||||
myLogHook :: X ()
|
||||
myLogHook = fadeInactiveLogHook fadeAmount
|
||||
where fadeAmount = 1.0
|
||||
|
||||
myKeys :: [(String, X ())]
|
||||
myKeys =
|
||||
-- Xmonad
|
||||
[ ("M-C-r", spawn "xmonad --recompile") -- Recompiles xmonad
|
||||
, ("M-S-r", spawn "xmonad --restart") -- Restarts xmonad
|
||||
, ("M-S-q", io exitSuccess) -- Quits xmonad
|
||||
|
||||
-- Run Prompt
|
||||
, ("M-S-<Return>", shellPrompt dtXPConfig) -- Xmonad Shell Prompt
|
||||
-- , ("M-S-<Return>", spawn "dmenu_run -i -p \"Run: \"") -- Dmenu
|
||||
-- , ("M-S-<Return>", spawn "rofi -show drun -config ~/.config/rofi/themes/dt-dmenu.rasi -display-drun \"Run: \" -drun-display-format \"{name}\"") -- Rofi
|
||||
|
||||
-- Other Prompts
|
||||
, ("M-p c", calcPrompt dtXPConfig' "qalc") -- calcPrompt
|
||||
, ("M-p m", manPrompt dtXPConfig) -- manPrompt
|
||||
, ("M-p p", passPrompt dtXPConfig) -- passPrompt
|
||||
, ("M-p g", passGeneratePrompt dtXPConfig) -- passGeneratePrompt
|
||||
, ("M-p r", passRemovePrompt dtXPConfig) -- passRemovePrompt
|
||||
, ("M-p s", sshPrompt dtXPConfig) -- sshPrompt
|
||||
, ("M-p u", mkUnicodePrompt "xsel" ["-b"] "/home/dt/.xmonad/UnicodeData.txt" emojiXPConfig) -- unicodePrompt (for copying emojis)
|
||||
, ("M-p x", xmonadPrompt dtXPConfig) -- xmonadPrompt
|
||||
|
||||
-- Useful programs to have a keybinding for launch
|
||||
, ("M-<Return>", spawn (myTerminal))
|
||||
, ("M-b", spawn (myBrowser ++ " www.youtube.com/c/DistroTube/"))
|
||||
, ("M-M1-h", spawn (myTerminal ++ " -e htop"))
|
||||
|
||||
-- Kill windows
|
||||
, ("M-S-c", kill1) -- Kill the currently focused client
|
||||
, ("M-S-a", killAll) -- Kill all windows on current workspace
|
||||
|
||||
-- Workspaces
|
||||
, ("M-.", nextScreen) -- Switch focus to next monitor
|
||||
, ("M-,", prevScreen) -- Switch focus to prev monitor
|
||||
, ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws
|
||||
, ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws
|
||||
|
||||
-- Floating windows
|
||||
, ("M-f", sendMessage (T.Toggle "floats")) -- Toggles my 'floats' layout
|
||||
, ("M-t", withFocused $ windows . W.sink) -- Push floating window back to tile
|
||||
, ("M-S-t", sinkAll) -- Push ALL floating windows to tile
|
||||
|
||||
-- Increase/decrease spacing (gaps)
|
||||
, ("M-d", decWindowSpacing 4) -- Decrease window spacing
|
||||
, ("M-i", incWindowSpacing 4) -- Increase window spacing
|
||||
, ("M-S-d", decScreenSpacing 4) -- Decrease screen spacing
|
||||
, ("M-S-i", incScreenSpacing 4) -- Increase screen spacing
|
||||
|
||||
-- Grid Select (CTR-g followed by a key)
|
||||
, ("C-g g", spawnSelected' myAppGrid) -- grid select favorite apps
|
||||
, ("C-g t", goToSelected $ mygridConfig myColorizer) -- goto selected window
|
||||
, ("C-g b", bringSelected $ mygridConfig myColorizer) -- bring selected window
|
||||
|
||||
-- Tree Select
|
||||
, ("C-t t", treeselectAction tsDefaultConfig)
|
||||
|
||||
-- Windows navigation
|
||||
, ("M-m", windows W.focusMaster) -- Move focus to the master window
|
||||
, ("M-j", windows W.focusDown) -- Move focus to the next window
|
||||
, ("M-k", windows W.focusUp) -- Move focus to the prev window
|
||||
, ("M-S-m", windows W.swapMaster) -- Swap the focused window and the master window
|
||||
, ("M-S-j", windows W.swapDown) -- Swap focused window with next window
|
||||
, ("M-S-k", windows W.swapUp) -- Swap focused window with prev window
|
||||
, ("M-<Backspace>", promote) -- Moves focused window to master, others maintain order
|
||||
, ("M-S-<Tab>", rotSlavesDown) -- Rotate all windows except master and keep focus in place
|
||||
, ("M-C-<Tab>", rotAllDown) -- Rotate all the windows in the current stack
|
||||
|
||||
-- Layouts
|
||||
, ("M-<Tab>", sendMessage NextLayout) -- Switch to next layout
|
||||
, ("M-C-M1-<Up>", sendMessage Arrange)
|
||||
, ("M-C-M1-<Down>", sendMessage DeArrange)
|
||||
, ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full
|
||||
, ("M-S-<Space>", sendMessage ToggleStruts) -- Toggles struts
|
||||
, ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder
|
||||
|
||||
-- Increase/decrease windows in the master pane or the stack
|
||||
, ("M-S-<Up>", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane
|
||||
, ("M-S-<Down>", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane
|
||||
, ("M-C-<Up>", increaseLimit) -- Increase number of windows
|
||||
, ("M-C-<Down>", decreaseLimit) -- Decrease number of windows
|
||||
|
||||
-- Window resizing
|
||||
, ("M-h", sendMessage Shrink) -- Shrink horiz window width
|
||||
, ("M-l", sendMessage Expand) -- Expand horiz window width
|
||||
, ("M-M1-j", sendMessage MirrorShrink) -- Shrink vert window width
|
||||
, ("M-M1-k", sendMessage MirrorExpand) -- Exoand vert window width
|
||||
|
||||
-- Sublayouts
|
||||
-- This is used to push windows to tabbed sublayouts, or pull them out of it.
|
||||
, ("M-C-h", sendMessage $ pullGroup L)
|
||||
, ("M-C-l", sendMessage $ pullGroup R)
|
||||
, ("M-C-k", sendMessage $ pullGroup U)
|
||||
, ("M-C-j", sendMessage $ pullGroup D)
|
||||
, ("M-C-m", withFocused (sendMessage . MergeAll))
|
||||
, ("M-C-u", withFocused (sendMessage . UnMerge))
|
||||
, ("M-C-/", withFocused (sendMessage . UnMergeAll))
|
||||
, ("M-C-.", onGroup W.focusUp') -- Switch focus to next tab
|
||||
, ("M-C-,", onGroup W.focusDown') -- Switch focus to prev tab
|
||||
|
||||
-- Scratchpads
|
||||
, ("M-C-<Return>", namedScratchpadAction myScratchPads "terminal")
|
||||
, ("M-C-c", namedScratchpadAction myScratchPads "mocp")
|
||||
|
||||
-- Controls for mocp music player (SUPER-u followed by a key)
|
||||
, ("M-u p", spawn "mocp --play")
|
||||
, ("M-u l", spawn "mocp --next")
|
||||
, ("M-u h", spawn "mocp --previous")
|
||||
, ("M-u <Space>", spawn "mocp --toggle-pause")
|
||||
|
||||
-- Emacs (CTRL-e followed by a key)
|
||||
, ("C-e e", spawn "emacsclient -c -a 'emacs'") -- start emacs
|
||||
, ("C-e b", spawn "emacsclient -c -a 'emacs' --eval '(ibuffer)'") -- list emacs buffers
|
||||
, ("C-e d", spawn "emacsclient -c -a 'emacs' --eval '(dired nil)'") -- dired emacs file manager
|
||||
, ("C-e i", spawn "emacsclient -c -a 'emacs' --eval '(erc)'") -- erc emacs irc client
|
||||
, ("C-e m", spawn "emacsclient -c -a 'emacs' --eval '(mu4e)'") -- mu4e emacs email client
|
||||
, ("C-e n", spawn "emacsclient -c -a 'emacs' --eval '(elfeed)'") -- elfeed emacs rss client
|
||||
, ("C-e s", spawn "emacsclient -c -a 'emacs' --eval '(eshell)'") -- eshell within emacs
|
||||
, ("C-e t", spawn "emacsclient -c -a 'emacs' --eval '(mastodon)'") -- mastodon within emacs
|
||||
, ("C-e v", spawn "emacsclient -c -a 'emacs' --eval '(+vterm/here nil)'") -- vterm within emacs
|
||||
-- emms is an emacs audio player. I set it to auto start playing in a specific directory.
|
||||
, ("C-e a", spawn "emacsclient -c -a 'emacs' --eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/Non-Classical/70s-80s/\")'")
|
||||
|
||||
-- Multimedia Keys
|
||||
, ("<XF86AudioPlay>", spawn (myTerminal ++ "mocp --play"))
|
||||
, ("<XF86AudioPrev>", spawn (myTerminal ++ "mocp --previous"))
|
||||
, ("<XF86AudioNext>", spawn (myTerminal ++ "mocp --next"))
|
||||
, ("<XF86AudioMute>", spawn "amixer set Master toggle")
|
||||
, ("<XF86AudioLowerVolume>", spawn "amixer set Master 5%- unmute")
|
||||
, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 5%+ unmute")
|
||||
, ("<XF86HomePage>", spawn "firefox")
|
||||
, ("<XF86Search>", safeSpawn "firefox" ["https://www.duckduckgo.com/"])
|
||||
, ("<XF86Mail>", runOrRaise "thunderbird" (resource =? "thunderbird"))
|
||||
, ("<XF86Calculator>", runOrRaise "qalculate-gtk" (resource =? "qalculate-gtk"))
|
||||
, ("<XF86Eject>", spawn "toggleeject")
|
||||
, ("<Print>", spawn "scrotd 0")
|
||||
]
|
||||
-- Appending search engine prompts to keybindings list.
|
||||
-- Look at "search engines" section of this config for values for "k".
|
||||
++ [("M-s " ++ k, S.promptSearch dtXPConfig' f) | (k,f) <- searchList ]
|
||||
++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
-- The following lines are needed for named scratchpads.
|
||||
where nonNSP = WSIs (return (\ws -> W.tag ws /= "nsp"))
|
||||
nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "nsp"))
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Launching three instances of xmobar on their monitors.
|
||||
xmproc0 <- spawnPipe "xmobar -x 0 $HOME/.config/xmobar/xmobarrc0"
|
||||
xmproc1 <- spawnPipe "xmobar -x 1 $HOME/.config/xmobar/xmobarrc2"
|
||||
xmproc2 <- spawnPipe "xmobar -x 2 $HOME/.config/xmobar/xmobarrc1"
|
||||
-- the xmonad, ya know...what the WM is named after!
|
||||
xmonad $ ewmh def
|
||||
{ manageHook = ( isFullscreen --> doFullFloat ) <+> myManageHook <+> manageDocks
|
||||
-- Run xmonad commands from command line with "xmonadctl command". Commands include:
|
||||
-- shrink, expand, next-layout, default-layout, restart-wm, xterm, kill, refresh, run,
|
||||
-- focus-up, focus-down, swap-up, swap-down, swap-master, sink, quit-wm. You can run
|
||||
-- "xmonadctl 0" to generate full list of commands written to ~/.xsession-errors.
|
||||
-- To compile xmonadctl: ghc -dynamic xmonadctl.hs
|
||||
, handleEventHook = serverModeEventHookCmd
|
||||
<+> serverModeEventHook
|
||||
<+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
|
||||
<+> docksEventHook
|
||||
, modMask = myModMask
|
||||
, terminal = myTerminal
|
||||
, startupHook = myStartupHook
|
||||
, layoutHook = showWName' myShowWNameTheme $ myLayoutHook
|
||||
, workspaces = myWorkspaces
|
||||
, borderWidth = myBorderWidth
|
||||
, normalBorderColor = myNormColor
|
||||
, focusedBorderColor = myFocusColor
|
||||
, logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP
|
||||
{ ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x
|
||||
, ppCurrent = xmobarColor "#98be65" "" . wrap "[" "]" -- Current workspace in xmobar
|
||||
, ppVisible = xmobarColor "#98be65" "" . clickable -- Visible but not current workspace
|
||||
, ppHidden = xmobarColor "#82AAFF" "" . wrap "*" "" . clickable -- Hidden workspaces in xmobar
|
||||
, ppHiddenNoWindows = xmobarColor "#c792ea" "" . clickable -- Hidden workspaces (no windows)
|
||||
, ppTitle = xmobarColor "#b3afc2" "" . shorten 60 -- Title of active window in xmobar
|
||||
, ppSep = "<fc=#666666> <fn=1>|</fn> </fc>" -- Separators in xmobar
|
||||
, ppUrgent = xmobarColor "#C45500" "" . wrap "!" "!" -- Urgent workspace
|
||||
, ppExtras = [windowCount] -- # of windows current workspace
|
||||
, ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
|
||||
}
|
||||
} `additionalKeysP` myKeys
|
||||
51
.xmonad/xmonadctl.hs
Normal file
51
.xmonad/xmonadctl.hs
Normal file
@@ -0,0 +1,51 @@
|
||||
import Graphics.X11.Xlib
|
||||
import Graphics.X11.Xlib.Extras
|
||||
import System.Environment
|
||||
import System.IO
|
||||
import Data.Char
|
||||
|
||||
main :: IO ()
|
||||
main = parse True "XMONAD_COMMAND" =<< getArgs
|
||||
|
||||
parse :: Bool -> String -> [String] -> IO ()
|
||||
parse input addr args = case args of
|
||||
["--"] | input -> repl addr
|
||||
| otherwise -> return ()
|
||||
("--":xs) -> sendAll addr xs
|
||||
("-a":a:xs) -> parse input a xs
|
||||
("-h":_) -> showHelp
|
||||
("--help":_) -> showHelp
|
||||
("-?":_) -> showHelp
|
||||
(a@('-':_):_) -> hPutStrLn stderr ("Unknown option " ++ a)
|
||||
|
||||
(x:xs) -> sendCommand addr x >> parse False addr xs
|
||||
[] | input -> repl addr
|
||||
| otherwise -> return ()
|
||||
|
||||
|
||||
repl :: String -> IO ()
|
||||
repl addr = do e <- isEOF
|
||||
case e of
|
||||
True -> return ()
|
||||
False -> do l <- getLine
|
||||
sendCommand addr l
|
||||
repl addr
|
||||
|
||||
sendAll :: String -> [String] -> IO ()
|
||||
sendAll addr ss = foldr (\a b -> sendCommand addr a >> b) (return ()) ss
|
||||
|
||||
sendCommand :: String -> String -> IO ()
|
||||
sendCommand addr s = do
|
||||
d <- openDisplay ""
|
||||
rw <- rootWindow d $ defaultScreen d
|
||||
a <- internAtom d addr False
|
||||
m <- internAtom d s False
|
||||
allocaXEvent $ \e -> do
|
||||
setEventType e clientMessage
|
||||
setClientMessageEvent e rw a 32 m currentTime
|
||||
sendEvent d rw False structureNotifyMask e
|
||||
sync d False
|
||||
|
||||
showHelp :: IO ()
|
||||
showHelp = do pn <- getProgName
|
||||
putStrLn ("Send commands to a running instance of xmonad. xmonad.hs must be configured with XMonad.Hooks.ServerMode to work.\n-a atomname can be used at any point in the command line arguments to change which atom it is sending on.\nIf sent with no arguments or only -a atom arguments, it will read commands from stdin.\nEx:\n" ++ pn ++ " cmd1 cmd2\n" ++ pn ++ " -a XMONAD_COMMAND cmd1 cmd2 cmd3 -a XMONAD_PRINT hello world\n" ++ pn ++ " -a XMONAD_PRINT # will read data from stdin.\nThe atom defaults to XMONAD_COMMAND.")
|
||||
25
.xmonad/xpm/calendar-clock-icon_20.xpm
Normal file
25
.xmonad/xpm/calendar-clock-icon_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * calendar_clock_icon_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ........ ",
|
||||
" .. .. ",
|
||||
" .. . .. ",
|
||||
" .. . .. ",
|
||||
" . . . ",
|
||||
" . . . ",
|
||||
" . . . ",
|
||||
" . ...... . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" ........ ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/cpu_20.xpm
Normal file
25
.xmonad/xpm/cpu_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * cpu_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ................ ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" ................ ",
|
||||
" .............. ",
|
||||
" .. ",
|
||||
" ........ ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/harddisk-icon_20.xpm
Normal file
25
.xmonad/xpm/harddisk-icon_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * harddisk_icon_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ............ ",
|
||||
" .. .. ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" .. .. ",
|
||||
" .. .. ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" .. .. ",
|
||||
" ............ ",
|
||||
" . ... . ",
|
||||
" ............ ",
|
||||
" ............ ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/haskell_20.xpm
Normal file
25
.xmonad/xpm/haskell_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * haskell_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #FFFFFF",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
".... .... ",
|
||||
" .... ... ",
|
||||
" ... .... ",
|
||||
" .... .... ",
|
||||
" .... ... ........",
|
||||
" ... .... .......",
|
||||
" .... .... ",
|
||||
" .... .... ",
|
||||
" ... ...... .....",
|
||||
" .... ....... ....",
|
||||
" .... .... ... ",
|
||||
" ... .... .... ",
|
||||
" .... ... .... ",
|
||||
".... .... ... ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/memory-icon_20.xpm
Normal file
25
.xmonad/xpm/memory-icon_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * memory_icon_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ........... ",
|
||||
" . . ",
|
||||
" . . . ",
|
||||
" . . . . . ",
|
||||
" . .. . .. . ",
|
||||
" . .. . .. . ",
|
||||
" . .. . .. . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" .. . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" . . ",
|
||||
" ............ ",
|
||||
" ............ ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/net_down_20.xpm
Normal file
25
.xmonad/xpm/net_down_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * net_down_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" .. . . ",
|
||||
" . . .. ",
|
||||
" .. . . ",
|
||||
" . ... ",
|
||||
" .... ",
|
||||
" ... ",
|
||||
" .. ",
|
||||
" . ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
25
.xmonad/xpm/net_up_20.xpm
Normal file
25
.xmonad/xpm/net_up_20.xpm
Normal file
@@ -0,0 +1,25 @@
|
||||
/* XPM */
|
||||
static char * net_up_20_xpm[] = {
|
||||
"20 20 2 1",
|
||||
" c None",
|
||||
". c #EFF0F1",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" . ",
|
||||
" .. ",
|
||||
" ... ",
|
||||
" .... ",
|
||||
" . ... ",
|
||||
" .. . . ",
|
||||
" . . .. ",
|
||||
" .. . . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" . ",
|
||||
" ",
|
||||
" "};
|
||||
Reference in New Issue
Block a user