diff --git a/.xmonad/README.org b/.xmonad/README.org index 3231f4b..d0a3273 100644 --- a/.xmonad/README.org +++ b/.xmonad/README.org @@ -4,10 +4,23 @@ * TABLE OF CONTENTS :toc: - [[#about-this-config][ABOUT THIS CONFIG]] - [[#imports][IMPORTS]] +- [[#variables][VARIABLES]] - [[#autostart][AUTOSTART]] +- [[#gridselect][GRIDSELECT]] +- [[#treeselect][TREESELECT]] + - [[#treeselect-menu-entries][TREESELECT MENU ENTRIES]] + - [[#treeselect-settings][TREESELECT SETTINGS]] +- [[#xprompts][XPROMPTS]] + - [[#xprompt-settings][XPROMPT SETTINGS]] + - [[#custom-prompts][CUSTOM PROMPTS]] + - [[#xprompt-keymap][XPROMPT KEYMAP]] + - [[#search-engines][SEARCH ENGINES]] +- [[#scratchpads][SCRATCHPADS]] +- [[#layouts][LAYOUTS]] - [[#workspaces][WORKSPACES]] - [[#managehook][MANAGEHOOK]] - [[#loghook][LOGHOOK]] +- [[#keybindings][KEYBINDINGS]] - [[#main][MAIN]] * ABOUT THIS CONFIG @@ -31,20 +44,31 @@ than a config that you should download and use. These are Haskell modules that we must import so that we can use their functions later in the config. #+BEGIN_SRC haskell - -- Custom (my personal configs) -import Custom.MyGridMenu -import Custom.MyKeys -import Custom.MyLayouts -import Custom.MyPrompts -import Custom.MyScratchpads -import Custom.MyTreeMenu -import Custom.MyVariables - - -- Base + -- Base import XMonad -import Data.Monoid 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(..)) @@ -56,6 +80,39 @@ 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 @@ -63,6 +120,45 @@ import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe) import XMonad.Util.SpawnOnce #+END_SRC +* 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. + +#+BEGIN_SRC haskell +myFont :: String +myFont = "xft:Mononoki Nerd Font:bold: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 firefox 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 = "#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 +#+END_SRC + * AUTOSTART These are commands we want XMonad to execute on startup, such as running a compositor, setting our wallpaper, starting the emacs daemon, and starting our system tray and the applications that belong in it. @@ -79,6 +175,617 @@ myStartupHook = do setWMName "LG3D" #+END_SRC + + +* GRIDSELECT +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. + +#+BEGIN_SRC haskell +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 + } + +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") + ] +#+END_SRC + +* TREESELECT +TreeSelect displays your workspaces or actions in a Tree-like format. +You can select desired workspace/action with the cursor or hjkl keys. +My TreeSelect menu is rather large and includes a mixture of applications, +web bookmarks, configuration files and xmonad actions. + +** TREESELECT MENU ENTRIES +#+BEGIN_SRC haskell +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 "Calibre" "Manages books on my ereader" (spawn "calibre")) [] + , Node (TS.TSNode "Castero" "Terminal podcast client" (spawn (myTerminal ++ " -e castero"))) [] + , Node (TS.TSNode "Picom Toggle on/off" "Compositor for window managers" (spawn "killall picom; picom")) [] + , 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 "Simple Scan" "A simple scanning program" (spawn "simple-scan")) [] + ] + , 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 "xxx")) [] + , Node (TS.TSNode "FileZilla" "An FTP client" (spawn "filezilla")) [] + , Node (TS.TSNode "Firefox" "Open source web browser" (spawn "firefox")) [] + , Node (TS.TSNode "Geary" "Email client with a nice UI" (spawn "geary")) [] + , Node (TS.TSNode "Jitsi" "Open source video chat" (spawn "xxx")) [] + , Node (TS.TSNode "Mu4e" "An Emacs email client" (spawn "xxx")) [] + , 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" "Emacs file manager" (spawn "xxx")) [] + , Node (TS.TSNode "Etcher" "USB stick writer" (spawn "xxx")) [] + , Node (TS.TSNode "Glances" "Terminal system monitor" (spawn (myTerminal ++ " -e glances"))) [] + , 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" (spawn "lxappearance")) [] + , Node (TS.TSNode "Nitrogen" "Wallpaper viewer and setter" (spawn "nitrogen")) [] + , Node (TS.TSNode "Nmon" "Network monitor" (spawn (myTerminal ++ " -e nmon"))) [] + , Node (TS.TSNode "PCManFM" "Lightweight graphical file manager" (spawn "pcmanfm")) [] + , Node (TS.TSNode "Simple Terminal" "Suckless simple terminal" (spawn "st")) [] + , Node (TS.TSNode "Stress Terminal UI" "Stress your system" (spawn (myTerminal ++ " -e vifm"))) [] + , Node (TS.TSNode "Vifm" "Vim-like file manager" (spawn (myTerminal ++ " -e vifm"))) [] + ] + , 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 "Awesome" "awesomewm documentation" (return ())) + [ Node (TS.TSNode "Awesome" "Homepage for awesome wm" (spawn (myBrowser ++ "https://awesomewm.org/"))) [] + , Node (TS.TSNode "Awesome GitHub" "The GutHub page for awesome" (spawn (myBrowser ++ "https://github.com/awesomeWM/awesome"))) [] + , Node (TS.TSNode "r/awesome" "Subreddit for awesome" (spawn (myBrowser ++ "https://www.reddit.com/r/awesomewm/"))) [] + ] + , Node (TS.TSNode "+ Dwm" "dwm documentation" (return ())) + [ Node (TS.TSNode "Dwm" "Dynamic window manager" (spawn (myBrowser ++ "https://dwm.suckless.org/"))) [] + , Node (TS.TSNode "Dwmblocks" "Modular status bar for dwm" (spawn (myBrowser ++ "https://github.com/torrinfail/dwmblocks"))) [] + , Node (TS.TSNode "r/suckless" "Subreddit for suckless software" (spawn (myBrowser ++ "https://www.reddit.com/r/suckless//"))) [] + ] + , Node (TS.TSNode "+ Qtile" "qtile documentation" (return ())) + [ Node (TS.TSNode "Qtile" "Tiling window manager in Python" (spawn (myBrowser ++ "http://www.qtile.org"))) [] + , Node (TS.TSNode "Qtile GitHub" "The GitHub page for qtile" (spawn (myBrowser ++ "https://github.com/qtile/qtile"))) [] + , Node (TS.TSNode "r/qtile" "Subreddit for qtile" (spawn (myBrowser ++ "https://www.reddit.com/r/qtile/"))) [] + ] + , 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 "+ Config Files" "config files that edit often" (return ())) + [ Node (TS.TSNode "+ emacs configs" "My xmonad config files" (return ())) + [ Node (TS.TSNode "doom emacs config.org" "doom emacs config" (spawn (myEditor ++ "/home/dt/.doom.d/config.org"))) [] + , Node (TS.TSNode "doom emacs init.el" "doom emacs init" (spawn (myEditor ++ "/home/dt/.doom.d/init.el"))) [] + , Node (TS.TSNode "doom emacs packages.el" "doom emacs packages" (spawn (myEditor ++ "/home/dt/.doom.d/packages.el"))) [] + ] + , Node (TS.TSNode "+ xmobar configs" "My xmobar config files" (return ())) + [ Node (TS.TSNode "xmobar mon1" "status bar on monitor 1" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc0"))) [] + , Node (TS.TSNode "xmobar mon2" "status bar on monitor 2" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc2"))) [] + , Node (TS.TSNode "xmobar mon3" "status bar on monitor 3" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc1"))) [] + ] + , Node (TS.TSNode "+ xmonad configs" "My xmonad config files" (return ())) + [ Node (TS.TSNode "xmonad.hs" "My XMonad Main" (spawn (myEditor ++ "/home/dt/.xmonad/xmonad.hs"))) [] + , Node (TS.TSNode "MyGridMenu.hs" "My XMonad GridSelect menu" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyGridMenu.hs"))) [] + , Node (TS.TSNode "MyKeys.hs" "My XMonad keybindings" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyKeys.hs"))) [] + , Node (TS.TSNode "MyLayouts.hs" "My XMonad layouts" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyLayouts.hs"))) [] + , Node (TS.TSNode "MyPrompts.hs" "My XMonad prompts" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyPrompts.hs"))) [] + , Node (TS.TSNode "MyScratchpads.hs" "My XMonad named scratchpads" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyScratchpads.hs"))) [] + , Node (TS.TSNode "MyTreeMenu.hs" "My XMonad TreeSelect menu" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyTreeMenu.hs"))) [] + , Node (TS.TSNode "MyVariables.hs" "My XMonad variables" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyVariables.hs"))) [] + ] + + , Node (TS.TSNode "alacritty" "alacritty terminal emulator" (spawn (myEditor ++ "/home/dt/.config/alacritty/alacritty.yml"))) [] + , Node (TS.TSNode "awesome" "awesome window manager" (spawn (myEditor ++ "/home/dt/.config/awesome/rc.lua"))) [] + , Node (TS.TSNode "bashrc" "the bourne again shell" (spawn (myEditor ++ "/home/dt/.bashrc"))) [] + , Node (TS.TSNode "bspwmrc" "binary space partitioning window manager" (spawn (myEditor ++ "/home/dt/.config/bspwm/bspwmrc"))) [] + , Node (TS.TSNode "dmenu config.h" "dynamic menu program" (spawn (myEditor ++ "/home/dt/dmenu-distrotube/config.h"))) [] + , Node (TS.TSNode "dunst" "dunst notifications" (spawn (myEditor ++ "/home/dt/.config/dunst/dunstrc"))) [] + , Node (TS.TSNode "dwm config.h" "dynamic window manager" (spawn (myEditor ++ "/home/dt/dwm-distrotube/config.h"))) [] + , Node (TS.TSNode "herbstluftwm" "herbstluft window manager" (spawn (myEditor ++ "/home/dt/.config/herbstluftwm/autostart"))) [] + , Node (TS.TSNode "neovim init.vim" "neovim text editor" (spawn (myEditor ++ "/home/dt/.config/nvim/init.vim"))) [] + , Node (TS.TSNode "polybar" "easy-to-use status bar" (spawn (myEditor ++ "/home/dt/.config/polybar/config"))) [] + , Node (TS.TSNode "qtile config.py" "qtile window manager" (spawn (myEditor ++ "/home/dt/.config/qtile/config.py"))) [] + , Node (TS.TSNode "qutebrowser config.py" "qutebrowser web browser" (spawn (myEditor ++ "/home/dt/.config/qutebrowser/config.py"))) [] + , Node (TS.TSNode "st config.h" "suckless simple terminal" (spawn (myEditor ++ "home/dt/st-distrotube/config.h"))) [] + , Node (TS.TSNode "sxhkdrc" "simple X hotkey daemon" (spawn (myEditor ++ "/home/dt/.config/sxhkd/sxhkdrc"))) [] + , Node (TS.TSNode "surf config.h" "surf web browser" (spawn (myEditor ++ "/home/dt/surf-distrotube/config.h"))) [] + , Node (TS.TSNode "tabbed config.h" "generic tabbed interface" (spawn (myEditor ++ "home/dt/tabbed-distrotube/config.h"))) [] + , Node (TS.TSNode "xresources" "xresources file" (spawn (myEditor ++ "/home/dt/.Xresources"))) [] + , Node (TS.TSNode "zshrc" "Config for the z shell" (spawn (myEditor ++ "/home/dt/.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 "+ XMonad" "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)) [] + ] + ] + #+END_SRC + +** TREESELECT SETTINGS +Configuration options for the treeSelect menus. +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. + + #+BEGIN_SRC haskell +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 + } + +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) + ] +#+END_SRC + +* XPROMPTS +** XPROMPT SETTINGS + +#+BEGIN_SRC haskell +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 + ] +#+END_SRC + +** CUSTOM PROMPTS +calcPrompt requires a cli calculator called qalcualte-gtk. +You could use this as a template for other custom prompts that + +#+BEGIN_SRC haskell +calcPrompt c ans = + inputPrompt c (trim ans) ?+ \input -> + liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c + where + trim = f . f + where f = reverse . dropWhile isSpace + +#+END_SRC + +** XPROMPT KEYMAP +Emacs-like key bindings for xprompts. + +#+BEGIN_SRC haskell +dtXPKeymap :: M.Map (KeyMask,KeySym) (XP ()) +dtXPKeymap = M.fromList $ + map (first $ (,) controlMask) -- control + + [ (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 + + [ (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) -- + [ (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) + ] +#+END_SRC + +** 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. + +#+BEGIN_SRC haskell +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) + ] +#+END_SRC + +* SCRATCHPADS +Allows to have several floating scratchpads running different applications. +Import Util.NamedScratchpad. Bind a key to namedScratchpadSpawnAction. + +#+BEGIN_SRC haskell +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 +#+END_SRC + +* LAYOUTS +Makes setting the spacingRaw simpler to write. The spacingRaw +module adds a configurable amount of space around windows. + +#+BEGIN_SRC haskell +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 +#+END_SRC + * WORKSPACES My workspaces are clickable meaning that the mouse can be used to switch workspaces. This requires xdotool. You need to use UnsafeStdInReader instead @@ -139,6 +846,145 @@ myLogHook = fadeInactiveLogHook fadeAmount where fadeAmount = 1.0 #+END_SRC + +* KEYBINDINGS +I am using the Xmonad.Util.EZConfig module which allows keybindings +to be written in simpler, emacs-like format. + +#+BEGIN_SRC haskell +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-", spawn myTerminal) + + -- Run Prompt + , ("M-S-", 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-", withFocused $ windows . W.sink) -- Push floating window back to tile + , ("M-S-", 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-M1-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-", promote) -- Moves focused window to master, others maintain order + , ("M1-S-", rotSlavesDown) -- Rotate all windows except master and keep focus in place + , ("M1-C-", rotAllDown) -- Rotate all the windows in the current stack + --, ("M-S-s", windows copyToAll) + , ("M-C-s", killAllOtherCopies) + + -- Layouts + , ("M-", sendMessage NextLayout) -- Switch to next layout + , ("M-C-M1-", sendMessage Arrange) + , ("M-C-M1-", sendMessage DeArrange) + , ("M-", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full + , ("M-S-", sendMessage ToggleStruts) -- Toggles struts + , ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder + , ("M-", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane + , ("M-", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane + , ("M-S-", increaseLimit) -- Increase number of windows + , ("M-S-", 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-", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws + , ("M-S-", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws + + -- Scratchpads + , ("M-C-", 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 ", 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 i", spawn "emacsclient -c -a '' --eval '(erc)'") -- erc emacs irc client + , ("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 '(mastodon)'") -- mastodon within emacs + , ("C-e v", spawn "emacsclient -c -a '' --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 '' --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 + , ("", spawn "cmus toggle") + , ("", spawn "cmus prev") + , ("", spawn "cmus next") + -- , ("", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04. + , ("", spawn "amixer set Master 5%- unmute") + , ("", spawn "amixer set Master 5%+ unmute") + , ("", spawn "firefox") + , ("", safeSpawn "firefox" ["https://www.google.com/"]) + , ("", runOrRaise "geary" (resource =? "thunderbird")) + , ("", runOrRaise "gcalctool" (resource =? "gcalctool")) + , ("", spawn "toggleeject") + , ("", 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")) +#+END_SRC + * MAIN This is the "main" of XMonad. This where everything in our configs comes together and works. diff --git a/.xmonad/xmonad.hs b/.xmonad/xmonad.hs index b36686a..bc36075 100644 --- a/.xmonad/xmonad.hs +++ b/.xmonad/xmonad.hs @@ -1,17 +1,28 @@ - -- Custom (my personal configs) -import Custom.MyGridMenu -import Custom.MyKeys -import Custom.MyLayouts -import Custom.MyPrompts -import Custom.MyScratchpads -import Custom.MyTreeMenu -import Custom.MyVariables - - -- Base + -- Base import XMonad -import Data.Monoid 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(..)) @@ -23,12 +34,77 @@ 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 +myFont :: String +myFont = "xft:Mononoki Nerd Font:bold: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 firefox 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 = "#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 + myStartupHook :: X () myStartupHook = do spawnOnce "nitrogen --restore &" @@ -40,6 +116,555 @@ myStartupHook = do -- spawnOnce "kak -d -s mysession &" setWMName "LG3D" +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 + } + +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 "Calibre" "Manages books on my ereader" (spawn "calibre")) [] + , Node (TS.TSNode "Castero" "Terminal podcast client" (spawn (myTerminal ++ " -e castero"))) [] + , Node (TS.TSNode "Picom Toggle on/off" "Compositor for window managers" (spawn "killall picom; picom")) [] + , 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 "Simple Scan" "A simple scanning program" (spawn "simple-scan")) [] + ] + , 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 "xxx")) [] + , Node (TS.TSNode "FileZilla" "An FTP client" (spawn "filezilla")) [] + , Node (TS.TSNode "Firefox" "Open source web browser" (spawn "firefox")) [] + , Node (TS.TSNode "Geary" "Email client with a nice UI" (spawn "geary")) [] + , Node (TS.TSNode "Jitsi" "Open source video chat" (spawn "xxx")) [] + , Node (TS.TSNode "Mu4e" "An Emacs email client" (spawn "xxx")) [] + , 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" "Emacs file manager" (spawn "xxx")) [] + , Node (TS.TSNode "Etcher" "USB stick writer" (spawn "xxx")) [] + , Node (TS.TSNode "Glances" "Terminal system monitor" (spawn (myTerminal ++ " -e glances"))) [] + , 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" (spawn "lxappearance")) [] + , Node (TS.TSNode "Nitrogen" "Wallpaper viewer and setter" (spawn "nitrogen")) [] + , Node (TS.TSNode "Nmon" "Network monitor" (spawn (myTerminal ++ " -e nmon"))) [] + , Node (TS.TSNode "PCManFM" "Lightweight graphical file manager" (spawn "pcmanfm")) [] + , Node (TS.TSNode "Simple Terminal" "Suckless simple terminal" (spawn "st")) [] + , Node (TS.TSNode "Stress Terminal UI" "Stress your system" (spawn (myTerminal ++ " -e vifm"))) [] + , Node (TS.TSNode "Vifm" "Vim-like file manager" (spawn (myTerminal ++ " -e vifm"))) [] + ] + , 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 "Awesome" "awesomewm documentation" (return ())) + [ Node (TS.TSNode "Awesome" "Homepage for awesome wm" (spawn (myBrowser ++ "https://awesomewm.org/"))) [] + , Node (TS.TSNode "Awesome GitHub" "The GutHub page for awesome" (spawn (myBrowser ++ "https://github.com/awesomeWM/awesome"))) [] + , Node (TS.TSNode "r/awesome" "Subreddit for awesome" (spawn (myBrowser ++ "https://www.reddit.com/r/awesomewm/"))) [] + ] + , Node (TS.TSNode "+ Dwm" "dwm documentation" (return ())) + [ Node (TS.TSNode "Dwm" "Dynamic window manager" (spawn (myBrowser ++ "https://dwm.suckless.org/"))) [] + , Node (TS.TSNode "Dwmblocks" "Modular status bar for dwm" (spawn (myBrowser ++ "https://github.com/torrinfail/dwmblocks"))) [] + , Node (TS.TSNode "r/suckless" "Subreddit for suckless software" (spawn (myBrowser ++ "https://www.reddit.com/r/suckless//"))) [] + ] + , Node (TS.TSNode "+ Qtile" "qtile documentation" (return ())) + [ Node (TS.TSNode "Qtile" "Tiling window manager in Python" (spawn (myBrowser ++ "http://www.qtile.org"))) [] + , Node (TS.TSNode "Qtile GitHub" "The GitHub page for qtile" (spawn (myBrowser ++ "https://github.com/qtile/qtile"))) [] + , Node (TS.TSNode "r/qtile" "Subreddit for qtile" (spawn (myBrowser ++ "https://www.reddit.com/r/qtile/"))) [] + ] + , 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 "+ Config Files" "config files that edit often" (return ())) + [ Node (TS.TSNode "+ emacs configs" "My xmonad config files" (return ())) + [ Node (TS.TSNode "doom emacs config.org" "doom emacs config" (spawn (myEditor ++ "/home/dt/.doom.d/config.org"))) [] + , Node (TS.TSNode "doom emacs init.el" "doom emacs init" (spawn (myEditor ++ "/home/dt/.doom.d/init.el"))) [] + , Node (TS.TSNode "doom emacs packages.el" "doom emacs packages" (spawn (myEditor ++ "/home/dt/.doom.d/packages.el"))) [] + ] + , Node (TS.TSNode "+ xmobar configs" "My xmobar config files" (return ())) + [ Node (TS.TSNode "xmobar mon1" "status bar on monitor 1" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc0"))) [] + , Node (TS.TSNode "xmobar mon2" "status bar on monitor 2" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc2"))) [] + , Node (TS.TSNode "xmobar mon3" "status bar on monitor 3" (spawn (myEditor ++ "/home/dt/.config/xmobar/xmobarrc1"))) [] + ] + , Node (TS.TSNode "+ xmonad configs" "My xmonad config files" (return ())) + [ Node (TS.TSNode "xmonad.hs" "My XMonad Main" (spawn (myEditor ++ "/home/dt/.xmonad/xmonad.hs"))) [] + , Node (TS.TSNode "MyGridMenu.hs" "My XMonad GridSelect menu" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyGridMenu.hs"))) [] + , Node (TS.TSNode "MyKeys.hs" "My XMonad keybindings" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyKeys.hs"))) [] + , Node (TS.TSNode "MyLayouts.hs" "My XMonad layouts" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyLayouts.hs"))) [] + , Node (TS.TSNode "MyPrompts.hs" "My XMonad prompts" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyPrompts.hs"))) [] + , Node (TS.TSNode "MyScratchpads.hs" "My XMonad named scratchpads" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyScratchpads.hs"))) [] + , Node (TS.TSNode "MyTreeMenu.hs" "My XMonad TreeSelect menu" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyTreeMenu.hs"))) [] + , Node (TS.TSNode "MyVariables.hs" "My XMonad variables" (spawn (myEditor ++ "/home/dt/.xmonad/lib/Custom/MyVariables.hs"))) [] + ] + + , Node (TS.TSNode "alacritty" "alacritty terminal emulator" (spawn (myEditor ++ "/home/dt/.config/alacritty/alacritty.yml"))) [] + , Node (TS.TSNode "awesome" "awesome window manager" (spawn (myEditor ++ "/home/dt/.config/awesome/rc.lua"))) [] + , Node (TS.TSNode "bashrc" "the bourne again shell" (spawn (myEditor ++ "/home/dt/.bashrc"))) [] + , Node (TS.TSNode "bspwmrc" "binary space partitioning window manager" (spawn (myEditor ++ "/home/dt/.config/bspwm/bspwmrc"))) [] + , Node (TS.TSNode "dmenu config.h" "dynamic menu program" (spawn (myEditor ++ "/home/dt/dmenu-distrotube/config.h"))) [] + , Node (TS.TSNode "dunst" "dunst notifications" (spawn (myEditor ++ "/home/dt/.config/dunst/dunstrc"))) [] + , Node (TS.TSNode "dwm config.h" "dynamic window manager" (spawn (myEditor ++ "/home/dt/dwm-distrotube/config.h"))) [] + , Node (TS.TSNode "herbstluftwm" "herbstluft window manager" (spawn (myEditor ++ "/home/dt/.config/herbstluftwm/autostart"))) [] + , Node (TS.TSNode "neovim init.vim" "neovim text editor" (spawn (myEditor ++ "/home/dt/.config/nvim/init.vim"))) [] + , Node (TS.TSNode "polybar" "easy-to-use status bar" (spawn (myEditor ++ "/home/dt/.config/polybar/config"))) [] + , Node (TS.TSNode "qtile config.py" "qtile window manager" (spawn (myEditor ++ "/home/dt/.config/qtile/config.py"))) [] + , Node (TS.TSNode "qutebrowser config.py" "qutebrowser web browser" (spawn (myEditor ++ "/home/dt/.config/qutebrowser/config.py"))) [] + , Node (TS.TSNode "st config.h" "suckless simple terminal" (spawn (myEditor ++ "home/dt/st-distrotube/config.h"))) [] + , Node (TS.TSNode "sxhkdrc" "simple X hotkey daemon" (spawn (myEditor ++ "/home/dt/.config/sxhkd/sxhkdrc"))) [] + , Node (TS.TSNode "surf config.h" "surf web browser" (spawn (myEditor ++ "/home/dt/surf-distrotube/config.h"))) [] + , Node (TS.TSNode "tabbed config.h" "generic tabbed interface" (spawn (myEditor ++ "home/dt/tabbed-distrotube/config.h"))) [] + , Node (TS.TSNode "xresources" "xresources file" (spawn (myEditor ++ "/home/dt/.Xresources"))) [] + , Node (TS.TSNode "zshrc" "Config for the z shell" (spawn (myEditor ++ "/home/dt/.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 "+ XMonad" "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 = 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 + } + +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) + ] + +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 + ] + +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 + + [ (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 + + [ (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) -- + [ (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 :: 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) + ] + +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 + +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 + xmobarEscape :: String -> String xmobarEscape = concatMap doubleLts where @@ -75,6 +700,138 @@ 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 + + -- Open my preferred terminal + , ("M-", spawn myTerminal) + + -- Run Prompt + , ("M-S-", 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-", withFocused $ windows . W.sink) -- Push floating window back to tile + , ("M-S-", 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-M1-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-", promote) -- Moves focused window to master, others maintain order + , ("M1-S-", rotSlavesDown) -- Rotate all windows except master and keep focus in place + , ("M1-C-", rotAllDown) -- Rotate all the windows in the current stack + --, ("M-S-s", windows copyToAll) + , ("M-C-s", killAllOtherCopies) + + -- Layouts + , ("M-", sendMessage NextLayout) -- Switch to next layout + , ("M-C-M1-", sendMessage Arrange) + , ("M-C-M1-", sendMessage DeArrange) + , ("M-", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full + , ("M-S-", sendMessage ToggleStruts) -- Toggles struts + , ("M-S-n", sendMessage $ MT.Toggle NOBORDERS) -- Toggles noborder + , ("M-", sendMessage (IncMasterN 1)) -- Increase number of clients in master pane + , ("M-", sendMessage (IncMasterN (-1))) -- Decrease number of clients in master pane + , ("M-S-", increaseLimit) -- Increase number of windows + , ("M-S-", 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-", shiftTo Next nonNSP >> moveTo Next nonNSP) -- Shifts focused window to next ws + , ("M-S-", shiftTo Prev nonNSP >> moveTo Prev nonNSP) -- Shifts focused window to prev ws + + -- Scratchpads + , ("M-C-", 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 ", 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 i", spawn "emacsclient -c -a '' --eval '(erc)'") -- erc emacs irc client + , ("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 '(mastodon)'") -- mastodon within emacs + , ("C-e v", spawn "emacsclient -c -a '' --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 '' --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 + , ("", spawn "cmus toggle") + , ("", spawn "cmus prev") + , ("", spawn "cmus next") + -- , ("", spawn "amixer set Master toggle") -- Bug prevents it from toggling correctly in 12.04. + , ("", spawn "amixer set Master 5%- unmute") + , ("", spawn "amixer set Master 5%+ unmute") + , ("", spawn "firefox") + , ("", safeSpawn "firefox" ["https://www.google.com/"]) + , ("", runOrRaise "geary" (resource =? "thunderbird")) + , ("", runOrRaise "gcalctool" (resource =? "gcalctool")) + , ("", spawn "toggleeject") + , ("", 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 :: IO () main = do -- Launching three instances of xmobar on their monitors.