all repos — xmonad-config @ 904a7edf2aedb48b0ce9825fd5c8a46e57847073

personal xmonad config

initial commit
la-ninpre leobrekalini@gmail.com
Wed, 07 Jul 2021 14:33:20 +0300
commit

904a7edf2aedb48b0ce9825fd5c8a46e57847073

A .gitignore

@@ -0,0 +1,7 @@

+*.o +*.hi +*.lock +.stack-work +xpm/tmp +xmonad.errors +xmonad-x86_64-linux
A .gitmodules

@@ -0,0 +1,9 @@

+[submodule "xmonad-git"] + path = xmonad-git + url = https://github.com/xmonad/xmonad +[submodule "xmonad-contrib-git"] + path = xmonad-contrib-git + url = https://github.com/xmonad/xmonad-contrib +[submodule "xmobar-git"] + path = xmobar-git + url = https://github.com/jaor/xmobar
A build

@@ -0,0 +1,9 @@

+#!/bin/sh +exec stack ghc -- \ + --make xmonad.hs \ + -i \ + -ilib \ + -fforce-recomp \ + -main-is main \ + -v0 \ + -o "$1"
A lib/LaNinpreConfig.hs

@@ -0,0 +1,437 @@

+{-# OPTIONS_HADDOCK ignore-exports, prune #-} +---------------------------------------------------------------------- +-- | +-- Module : LaNinpreConfig +-- Description : personal stuff for xmonad +-- Maintainer : la-ninpre +-- +-- this module exists because i find it more convenient to manage some things +-- from here instead of doing it right in xmonad config +-- +---------------------------------------------------------------------- + +module LaNinpreConfig ( + -- * global + -- $global + myFonts, + myColor, + myModMask, + myTerminal, + myBrowser, + myGeminiClient, + myFileMgr, + myMocp, + myEditor, + myBorderWidth, + myNormColor, + myFocusColor, + myAppGrid, + myWorkspaces, + myScratchPads, + myManageHook, + myStartupHook + ) where + +import Data.List +import Data.Map as M +import Data.Maybe +import Data.Monoid + +import XMonad +import qualified XMonad.StackSet as W +import XMonad.Hooks.ManageHelpers +import XMonad.Hooks.SetWMName +import XMonad.Util.NamedScratchpad +import XMonad.Util.SpawnOnce + +-- $global +-- +-- constants and functions starting with \'my\' are exported and used in +-- xmonad config. + +-- * constants + +-- $constants +-- these are set up to avoid unnecessary repetition of replacements, when +-- things change. + +-- ** fonts +-- +-- $fonts +-- default fonts and helper functions for them. + +-- | default lato font +fontLatoDef = fontXft "Lato" "regular" 14 + +-- | font for @ShowWMName@ +-- +-- normal variant +-- +-- > fontSWN = fontXft "Press Start 2P" "regular" 60 +-- +-- sitelen pona pona variant +-- +-- > fontSWN = fontXft "sitelen\\-pona" "regular" 80 +fontSWN = fontXft "linja pona" "regular" 80 + +-- | fonts list +myFonts :: [String] +myFonts = [ fontLatoDef + , fontSWN + ] + +-- *** helper functions +-- +-- | font constructor +-- +-- it is just a helper function to simplify the process of specifying font +-- with xft. +fontXft :: String -- ^ font family + -> String -- ^ font style + -> Int -- ^ font style + -> String + +fontXft font style size = intercalate ":" [ "xft" + , font + , style + , "size=" ++ (show size) + , "antialias=true" + , "hinting=true" + ] + + +-- ** colors + +-- $colorTheme +-- +-- > bg #19191a +-- > fg #cadcde +-- > grey0 #232324 +-- > grey1 #363638 +-- > grey2 #66666a +-- > black #393838 +-- > red #c74444 +-- > green #7f9848 +-- > yellow #d7a06d +-- > blue #4e96d5 +-- > magenta #bc5fa7 +-- > cyan #55b795 +-- > white #c3b2f7 +-- > black-bright #5a514b +-- > red-bright #ed7c68 +-- > green-bright #c7ea76 +-- > yellow-bright #ffdb9d +-- > blue-bright #a6d5fe +-- > magenta-bright #edbbe9 +-- > cyan-bright #7fe2c5 +-- > white-bright #e2d6ff + +-- | color theme structure +myColorTheme :: [(String,String)] +myColorTheme = [ ("bg", "#19191a") + , ("fg", "#cadcde") + , ("gray0", "#232324") + , ("gray1", "#363638") + , ("gray2", "#5c5c60") + , ("gray3", "#66666a") + , ("gray4", "#ececf0") + , ("black", "#393838") + , ("red", "#c74444") + , ("green", "#7f9848") + , ("yellow", "#d7a06d") + , ("blue", "#4e96d5") + , ("magenta", "#bc5fa7") + , ("cyan", "#55b795") + , ("white", "#c3b2f7") + , ("black-bright", "#5a514b") + , ("red-bright", "#ed7c68") + , ("green-bright", "#c7ea76") + , ("yellow-bright", "#ffdb9d") + , ("blue-bright", "#a6d5fe") + , ("magenta-bright", "#edbbe9") + , ("cyan-bright", "#7fe2c5") + , ("white-bright", "#e2d6ff") + ] + +-- | unfocused window border colour +myNormColor :: String +myNormColor = myColor "gray0" + +-- | focused window border colour +myFocusColor :: String +myFocusColor = myColor "blue" + +-- *** helper functions +-- +-- | get color from color theme +myColor :: String -> String +myColor c = fromMaybe "" (M.lookup c theme) + where + theme = fromList myColorTheme + + +-- ** software constants +-- +-- | set terminal emulator +myTerminal :: String +myTerminal = "alacritty" + +-- | set default browser +myBrowser :: String +myBrowser = "brave" + +-- | set gemini client +myGeminiClient :: String +myGeminiClient = "amfora" + +-- | set file manager +myFileMgr :: String +myFileMgr = "thunar" + +-- | music on console +-- +-- this is to avoid spamming strings everywhere. @moc@ doesn't comply with +-- XDG_CONFIG_HOME, so we force it to do so. +myMocp :: String +myMocp = "mocp -M '~/.config/moc'" + +-- | set editor +myEditor :: String +myEditor = myTerminal ++ " -e vim" + +-- ** other constants +-- +-- | set windows key as modkey +myModMask :: KeyMask +myModMask = mod4Mask + +-- | specify border width +myBorderWidth :: Dimension +myBorderWidth = 1 + +-- | app grid for @GridSelect@ layout +myAppGrid :: [(String,String)] +myAppGrid = [ ("discord", "discord") + , ("steam", "steam") + , ("cadence", "cadence") + , ("blender", "blender") + , ("inkscape", "inkscape") + , ("obs", "obs") + , ("gimp", "gimp") + , ("element", "element-desktop") + , ("ardour", "ardour6") + , ("kdenlive", "kdenlive") + , ("writer", "lowriter") + ] + +-- * hooks +-- +-- ** startup hook +-- +-- $startupHook +-- +-- start things at login. + +-- | actual instance +myStartupHook :: X () +myStartupHook = do + spawnOnce "dunst &" + spawnOnce "lxsession &" + spawnOnce "picom &" + spawnOnce "nm-applet &" + spawnOnce "volumeicon &" + spawnOnce "setxkbmap -layout us,ru -option 'grp:alt_shift_toggle'" + spawnOnce "kbdd" + spawnOnce ("trayer --edge top " + ++ "--align right " + ++ "--widthtype request " + ++ "--SetDockType true --SetPartialStrut true --expand false " + ++ "--monitor 0 --transparent true --alpha 0 " + ++ "--tint 0x19191a --height 24 &" + ) + spawnOnce "nitrogen --restore &" + setWMName "LG3D" + +-- ** manage hook +-- +-- $managehook +-- +-- @doFloat@ forces a window to float. useful for dialog boxes and such. +-- 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 be very long if using clickable workspaces. + +-- | manage hook +myManageHook :: Query (Endo WindowSet) +myManageHook = composeAll + [ className =? "confirm" --> doFloat + , className =? "file_progress" --> doFloat + , className =? "dialog" --> doFloat + , className =? "download" --> doFloat + , className =? "error" --> doFloat + , className =? "Gimp" --> doFloat + , className =? "notification" --> doFloat + , className =? "pinentry-gtk-2" --> doFloat + , className =? "splash" --> doFloat + , className =? "toolbar" --> doFloat + , className =? "Cadence" --> doFloat + , className =? "Steam" --> doFloat + , className =? "Image Lounge" --> doFloat + , title =? "Oracle VM VirtualBox Manager" --> doFloat + -- web workspace + , title =? "Mozilla Firefox" --> doShift ( myWorkspaces !! 1 ) + , className =? "Brave-browser" --> doShift ( myWorkspaces !! 1 ) + , className =? "amfora" --> doShift ( myWorkspaces !! 1 ) + , className =? "qutebrowser" --> doShift ( myWorkspaces !! 1 ) + -- doc workspace + , className =? "Geary" --> doShift ( myWorkspaces !! 3 ) + , className =? "libreoffice-writer" --> doShift ( myWorkspaces !! 3 ) + , className =? "libreoffice-impress" --> doShift ( myWorkspaces !! 3 ) + -- vm workspace + , className =? "VirtualBox Manager" --> doShift ( myWorkspaces !! 4 ) + -- chat workspace + , className =? "discord" --> doShift ( myWorkspaces !! 5 ) + , className =? "TelegramDesktop" --> doShift ( myWorkspaces !! 5 ) + , className =? "Element" --> doShift ( myWorkspaces !! 5 ) + , className =? "Steam" --> doShift ( myWorkspaces !! 5 ) + -- full workspace + , isFullscreen --> doShift ( myWorkspaces !! 6 ) + -- vid workspace + , className =? "Deadbeef" --> doShift ( myWorkspaces !! 7 ) + , appName =? "mpv" --> doShift ( myWorkspaces !! 7 ) + , className =? "vlc" --> doShift ( myWorkspaces !! 7 ) + -- gfx workspace + , className =? "Gimp" --> doShift ( myWorkspaces !! 8 ) + , className =? "Blender" --> doShift ( myWorkspaces !! 8 ) + , className =? "obs" --> doShift ( myWorkspaces !! 8 ) + , isFullscreen --> doFullFloat + ] <+> namedScratchpadManageHook myScratchPads + +-- * scratchpads +-- +-- $scratchpads +-- +-- currently i have: +-- +-- * plain terminal scratchpad +-- +-- * music on console +-- +-- * calculator (qalculate-gtk) +-- +-- * mpv instance that plays playlist in @~\/Video\/sp_playlist.m3u@ + +-- | scratchpad list +myScratchPads :: [NamedScratchpad] +myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm + , NS "mocp" spawnMocp findMocp manageMocp + , NS "calculator" spawnCalc findCalc manageCalc + , NS "mpvfloat" spawnMpv findMpv manageMpv + ] + where + -- terminal + spawnTerm = myTerminal ++ " -t scratchpad" + findTerm = title =? "scratchpad" + manageTerm = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + -- music on console + spawnMocp = myTerminal ++ " -t mocp -e " ++ myMocp + findMocp = title =? "mocp" + manageMocp = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 - h + l = 0.95 - w + -- calculator + spawnCalc = "qalculate-gtk" + findCalc = className =? "Qalculate-gtk" + manageCalc = customFloating $ W.RationalRect l t w h + where + h = 0.5 + w = 0.4 + t = 0.75 - h + l = 0.70 - w + -- mpv scratchpad to watch some stuff listed in ~/Video/sp_playlist.m3u + spawnMpv = "mpv --pause -x11-name mpv-sp ~/Video/sp_playlist.m3u" + ++ mpvGeometry mpvPercentage mpvPercentage + findMpv = appName =? "mpv-sp" + manageMpv = customFloating $ W.RationalRect l t w h + where + h = mpvPercentage + w = mpvPercentage + t = 0.03 + l = 0.996 - w + +-- ** helper functions +-- +-- | percentage of mpv scratchpad at start +mpvPercentage :: Rational +mpvPercentage = 1/4 + +-- | mpv needs geometry of window at start, so it won't resize itself, when +-- playing next video on a playlist +mpvGeometry :: RealFrac a + => a -- ^ relative height of window + -> a -- ^ relative width of window + -> String + +mpvGeometry h w = " --geometry=" ++ (show pw) ++ "x" ++ (show ph) + where + pw = ceiling (1920 * w) + ph = ceiling (1080 * h) + +-- * workspaces +-- +-- $workspaces +-- +-- i've got three ways of specifying them. first one is pretty close to the +-- original dt's config. second is using sitelen pona pona font by jackhumbert +-- (check it out [here](https://jackhumbert.github.io/sitelen-pona-pona/)). +-- and third one is using linja pona font by jan same +-- (check it out [here](http://musilili.net/linja-pona/)). +-- +-- * normal variant +-- +-- > myWorkspaces = [ "dev" +-- > , "www" +-- > , "sys" +-- > , "doc" +-- > , "vm" +-- > , "chat" +-- > , "full" +-- > , "vid" +-- > , "gfx" +-- > ] +-- +-- * one using sitelen pona pona by jackhumbert +-- +-- this is specified with actual glyph codes because xmobar +-- don't allow for ligatures and otf features. +-- +-- > myWorkspaces = [ "\xee3d" -- nanpa +-- > , "\xee3b" -- musi +-- > , "\xee49" -- pali +-- > , "\xee2a" -- lipu +-- > , "\xee53" -- poki +-- > , "\xee6c" -- toki +-- > , "\xee63" -- suli +-- > , "\xee60" -- sitelen +-- > , "\xee1e" -- kule +-- > ] + +-- | workspaces container +myWorkspaces = [ "\xe661\xe921" -- sona nanpa + , "\xe63b" -- musi + , "\xe649" -- pali + , "\xe62a\xf105" -- lipu ale + , "\xe653\xf115" -- poki ilo + , "\xe66c" -- toki + , "\xe62a\xf200" -- lipu suli + , "\xf010\xe915" -- sitelen tawa + , "\xf010\xf107" -- sitelen ante + ]
A stack.yaml

@@ -0,0 +1,73 @@

+# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# https://docs.haskellstack.org/en/stable/yaml_configuration/ + +# Resolver to choose a 'specific' stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# resolver: lts-3.5 +# resolver: nightly-2015-09-21 +# resolver: ghc-7.10.2 +# +# The location of a snapshot can be provided as a file or url. Stack assumes +# a snapshot provided as a file might change, whereas a url resource does not. +# +# resolver: ./custom-snapshot.yaml +# resolver: https://example.com/snapshots/2018-01-01.yaml +resolver: + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/1.yaml + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# subdirs: +# - auto-update +# - wai +packages: +- xmobar-git +- xmonad-git +- xmonad-contrib-git +# Dependency packages to be pulled from upstream that are not in the resolver. +# These entries can reference officially published versions as well as +# forks / in-progress versions pinned to a git hash. For example: +# +# extra-deps: +# - acme-missiles-0.3 +# - git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# +# extra-deps: [] + +# Override default flag values for local packages and extra-deps +flags: + xmobar: + with_xft: true + with_xpm: true + with_utf8: true + +# Extra package databases containing global packages +# extra-package-dbs: [] + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=2.7" +# +# Override the architecture used by stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor
A xmobar/separator.sh

@@ -0,0 +1,3 @@

+#!/bin/sh + +echo "<fc=#66666a>|</fc>"
A xmobar/trayer-padding-icon.sh

@@ -0,0 +1,48 @@

+#!/bin/sh +# Copied from https://github.com/jaor/xmobar/issues/239#issuecomment-233206552 +# Detects the width of running trayer-srg window (xprop name 'panel') +# and creates an XPM icon of that width, 1px height, and transparent. +# Outputs an <icon>-tag for use in xmobar to display the generated +# XPM icon. +# +# Run script from xmobar: +# `Run Com "/where/ever/trayer-padding-icon.sh" [] "trayerpad" 10` +# and use `%trayerpad%` in your template. + + +# Function to create a transparent Wx1 px XPM icon +create_xpm_icon () { + timestamp=$(date) + pixels=$(for i in `seq $1`; do echo -n "."; done) + + cat << EOF > "$2" +/* XPM * +static char * trayer_pad_xpm[] = { +/* This XPM icon is used for padding in xmobar to */ +/* leave room for trayer-srg. It is dynamically */ +/* updated by by trayer-padding-icon.sh which is run */ +/* by xmobar. */ +/* Created: ${timestamp} */ +/* <w/cols> <h/rows> <colors> <chars per pixel> */ +"$1 1 1 1", +/* Colors (none: transparent) */ +". c none", +/* Pixels */ +"$pixels" +}; +EOF +} + +# Width of the trayer window +width=$(xprop -name panel | grep 'program specified minimum size' | cut -d ' ' -f 5) + +# Icon file name +iconfile="$HOME/.xmonad/xpm/tmp/trayer-padding-${width}px.xpm" + +# If the desired icon does not exist create it +if [ ! -f $iconfile ]; then + create_xpm_icon $width $iconfile +fi + +# Output the icon tag for xmobar +echo "<icon=${iconfile}/>"
A xmobar/xmobarrc

@@ -0,0 +1,107 @@

+-- https://projects.haskell.org/xmobar/ +-- uses font awesome +-- vim:se syntax=haskell: + +Config { font = "xft:Lato:weight=bold:pixelsize=12:antialias=true:hinting=true" + , additionalFonts = [ "xft:Font Awesome 5 Free Solid:pixelsize=12" + , "xft:Font Awesome 5 Brands:pixelsize=14" + -- sitelen pona pona by jackhumbert + --, "xft:sitelen\-pona:pixelsize=20:antialias=true:hinting=true" + -- linja pona + , "xft:linja pona:pixelsize=22:antialias=true:hinting=true" + ] + , bgColor = "#19191a" + , fgColor = "#cadcde" + , position = TopSize C 100 24 + , lowerOnStart = True + , hideOnStart = False + , persistent = True + , iconRoot = ".xmonad/xpm/" + , commands = [ Run UnsafeStdinReader + , Run Com "uname" ["-r"] "" 0 + , Run Uptime + ["-t" + -- normie + --, "<fc=#7f9848><fn=1>\xf017</fn> uptime: <days>d</fc>" + -- sitelen pona pona by jackhumbert + --, "<fc=#7f9848><fn=3>\xee6b\xee64\xee3d</fn><days></fc>" + -- linja pona + , "<fc=#7f9848><fn=3>\xe66b\xe664\xe63d</fn><days></fc>" + -- tenpo suno nanpa + ] 60 + , Run Cpu + ["-t" + -- normie + --, "<fc=#c74444><fn=1>\xf108</fn>cpu: <total>%</fc>" + -- sitelen pona pona by jackhumbert + --, "<fc=#c74444><fn=3>\xee24\xee4d\xee0e\xee3d</fn>: <total>%</fc>" + -- linja pona + , "<fc=#c74444><fn=3>\xe624\xe730\xe60e\xe63d</fn>: <total>%</fc>" + -- lawa pi ilo sona + , "-H", "50", "--high", "red" + ] 20 + , Run Memory + ["-t" + -- normie + --, "<fc=#d7a06d><fn=1>\xf538</fn> ram: <used>M (<usedratio>%)</fc>" + -- sitelen pona pona by jackhumbert + --, "<fc=#d7a06d><fn=3>\xee53\xee49</fn>: <used>M (<usedratio>%)</fc>" + -- linja pona + , "<fc=#d7a06d><fn=3>\xe653\xf174</fn>: <used>M (<usedratio>%)</fc>" + -- poki pali + ] 20 + , Run DiskU + [("/home" + -- normie + --, "<fc=#4e96d5><fn=1>\xf0a0</fn> hdd: <free> free</fc>") + -- sitelen pona pona by jackhumbert + --, "<fc=#4e96d5><fn=3>\xee53\xee08</fn>: <free></fc>") + -- linja pona + , "<fc=#4e96d5><fn=3>\xe653\xf109</fn>: <free></fc>") + -- poki awen + ] [] 60 + , Run Kbd + -- normie + --[ ("us", "<fc=#55b795><fn=1>\xf11c</fn> EN</fc>") + --, ("ru", "<fc=#55b795><fn=1>\xf11c</fn> RU</fc>") + --] + -- sitelen pona pona by jackhumbert + --[ ("us", "<fc=#55b795><fn=3>\xee6c\xee4d\xee0e\xee60 inli</fn></fc>") + --, ("ru", "<fc=#55b795><fn=3>\xee6c\xee4d\xee0e\xee60 losi</fn></fc>") + --] + -- toki pi ilo sitelen + -- linja pona + [ ("us", "<fc=#55b795><fn=3>\xe66c\xe730\xe619\xe660 [_I_N_LI]</fn></fc>") + , ("ru", "<fc=#55b795><fn=3>\xe66c\xe730\xe619\xe660 [_L_O_SI]</fn></fc>") + ] + -- toki pi ilo sitelen + , Run Date + -- normie + --"<fc=#ceced2><fn=1>\xf017</fn> %d %b %Y %R</fc>" + -- sitelen pona pona by jackhumbert + --"<fc=#ceced2><fn=3>\xee6b</fn> %d-%m-%Y %R</fc>" + -- linja pona + "<fc=#ceced2><fn=3>\xe66b</fn> %d-%m-%Y %R</fc>" + -- tenpo + "date" 50 + , Run Network "wg0" + ["-t" + -- normie + --, "<fc=#ceced2><fn=1>\xf6d5</fn></fc>" + -- sitelen pona pona by jackhumbert + --, "<fc=#ceced2><fn=3>\xee01</fn></fc>" + -- linja pona + , "<fc=#ceced2><fn=3>\xe601</fn></fc>" + -- akesi + ] 20 + , Run Com ".xmonad/xmobar/trayer-padding-icon.sh" + ["panel"] "trayerpad" 10 + , Run Com ".xmonad/xmobar/separator.sh" [] "s" 0 + ] + , sepChar = "%" + , alignSep = "}{" + -- ... }{ <fc=#ceced2><fn=2></fn> ... -- normie + -- ... }{ <fc=#ceced2><fn=3> linu</fn> ... -- sitelen pona pona by jackhumbert + -- ... }{ <fc=#ceced2><fn=3> [_L_IN_U]</fn> ... -- linja pona + , template = " <action=`dm-logout`><icon=la_ninpre.xpm/></action> %s% %UnsafeStdinReader% }{ <fc=#ceced2><fn=3> [_L_IN_U]</fn> <action=`alacritty --class Alacritty,splash --hold -e neofetch`>%uname%</action></fc> %s% %uptime% %s% <action=`alacritty -e htop`>%cpu%</action> %s% <action=`alacritty -e htop`>%memory%</action> %s% <action=`alacritty --class Alacritty,splash --hold -e df -h / /timeshift /home`>%disku%</action> %s% %kbd% %s% <action=`alacritty -e calcurse`>%date%</action> %s% %wg0% %trayerpad%" +}
A xmobar/xmobarrc.bak

@@ -0,0 +1,30 @@

+Config { font = "xft:Jet Brains Mono:pixelsize=12:antialias=true;hinting=true" + , additionalFonts = [] + , bgColor = "#2e3440" + , fgColor = "#d8dee9" + , position = Top + , lowerOnStart = True + , hideOnStart = False + , allDesktops = True + , persistent = True + , iconRoot = "/home/aaoth/.xmonad/xpm/" -- default: "." + , commands = [ + -- Time and date + Run Date "%b %d %Y %H:%M" "date" 50 + -- Network up and down + , Run Network "eno1" ["-t", "<rx>kb <tx>kb"] 20 + , Run Network "wg0" ["-t", "<rx>kb <tx>kb"] 20 + -- Cpu usage in percent + , Run Cpu ["-t", "<total>%","-H","50","--high","red"] 20 + -- Ram used number and percent + , Run Memory ["-t", "<used>M (<usedratio>%)"] 20 + -- Disk space free + , Run DiskU [("/", "<free> free")] [] 60 + -- Runs a standard shell command 'uname -r' to get kernel version + , Run Com "uname" ["-r"] "" 3600 + ] + , sepChar = "%" + , alignSep = "}{" + , template = "<icon=haskell_20.xpm/>}{%uname% <fc=#666666>|</fc> <icon=cpu_20.xpm/> %cpu% <fc=#666666>|</fc> <icon=memory-icon_20.xpm/> %memory% <fc=#666666>|</fc> <icon=harddisk-icon_20.xpm/> %disku% <fc=#666666>|</fc> %eno1% wg: %wg0% <fc=#666666>|</fc> %date% " + } +
A xmonad.desktop

@@ -0,0 +1,9 @@

+[Desktop Entry] +Name=xmonad +Comment=A lightweight window manager written and configured in Haskell +Exec=xmonad +Icon=xmonad +Terminal=false +StartupNotify=false +X-DesktopNames=XMonad +Type=Application
A xmonad.hs

@@ -0,0 +1,476 @@

+{-# OPTIONS_HADDOCK prune #-} +---------------------------------------------------------------------- +-- | +-- Description : la-ninpre xmobar config +-- Maintainer : la-ninpre +-- +-- personal xmobar config. based heavily on distrotube's config. +-- i've added some stuff and toki pona fonts +-- +---------------------------------------------------------------------- + +module Main where + +import System.Directory +import System.IO (hPutStrLn) +import System.Exit (exitSuccess) + +import Data.Char (isSpace, toUpper) +import Data.Maybe (fromJust) +import Data.Monoid +import Data.Maybe (isJust) +import Data.Tree +import Data.List +import qualified Data.Map as M + +import XMonad +import qualified XMonad.StackSet as W + +import XMonad.Actions.CopyWindow (kill1) +import XMonad.Actions.CycleWS ( Direction1D(..) + , moveTo + , shiftTo + , WSType(..) + , nextScreen + , prevScreen + ) +import XMonad.Actions.GridSelect +import XMonad.Actions.MouseResize +import XMonad.Actions.Promote +import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown) +import XMonad.Actions.WindowGo (runOrRaise) +import XMonad.Actions.WithAll (sinkAll, killAll) +import qualified XMonad.Actions.Search as S + +import XMonad.Hooks.DynamicLog +import XMonad.Hooks.EwmhDesktops +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 + +import XMonad.Layout.SimplestFloat +import XMonad.Layout.ResizableTile +import XMonad.Layout.Tabbed +import XMonad.Layout.ThreeColumns +import XMonad.Layout.Accordion +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 qualified XMonad.Layout.BoringWindows as BW +import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..)) +import qualified XMonad.Layout.ToggleLayouts as T ( toggleLayouts + , ToggleLayout(Toggle) + ) +import qualified XMonad.Layout.MultiToggle as MT (Toggle(..)) + +import XMonad.Util.Dmenu +import XMonad.Util.Loggers +import XMonad.Util.EZConfig (additionalKeysP) +import XMonad.Util.NamedScratchpad +import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe) +import XMonad.Util.SpawnOnce +import XMonad.Util.WorkspaceCompare + +import LaNinpreConfig + +-- * misc functions +-- +-- | hides workspaces that have no windows +myHiddenNoWindows :: WorkspaceId -> String +myHiddenNoWindows = const "" + +mySuperscript :: Int -> String +mySuperscript n = map ss $ show n + where ss c | c == '0' = '⁰' + | c == '1' = '¹' + | c == '2' = '²' + | c == '3' = '³' + | c == '4' = '⁴' + | c == '5' = '⁵' + | c == '6' = '⁶' + | c == '7' = '⁷' + | c == '8' = '⁸' + | c == '9' = '⁹' + | otherwise = c + + +-- | window count logger +-- +-- gets number of windows on current workspace +myWindowCountLogger :: Logger +myWindowCountLogger = gets $ Just . show . length . W.integrate' . W.stack + . W.workspace . W.current . windowset + +myTestLogger :: Logger +myTestLogger = gets $ Just . xmobarColor (myColor "yellow") "" . intercalate " " + . \s -> ( let w = windowset $ s + ws = map W.workspace (W.current w : W.visible w) ++ W.hidden w + t = map (wrap "<fn=3>" "</fn>") . map W.tag $ ws + l = map length + . map W.integrate' + . map W.stack $ ws + in zipWith (++) t $ map mySuperscript l + ) + + +-- * grid select +-- +-- $gridSelect +-- +-- this section provides theming of @GridSelect@ stuff. +-- +-- here, @GridSelect@ is used for following things: +-- +-- * spawning some frequently used programs +-- +-- * moving to desired window +-- +-- * bringing the desired window to the current workspace + +-- | custom colorizer that colors windows based on their class +myColorizer :: Window -> Bool -> X (String, String) +myColorizer = colorRangeFromClassName + (0x00,0x00,0x00) -- lowest inactive bg + (0xbd,0x9c,0xf9) -- highest inactive bg + (0xc7,0x92,0xea) -- active bg + (0xc0,0xa7,0x9a) -- inactive fg + (0x28,0x2c,0x34) -- active fg + +-- | gridSelect config +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 = (myFonts !! 0) + } + +-- | spawn selected programs with grid select +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 = (myFonts !! 0) + } + +-- * layouts +-- +-- ** spacing raw helper functions +-- +-- $spacingHelpers +-- +-- theese are making calls to spacingRaw simpler to write + +-- | for many 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 + +-- | for fewer than two windows +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 + +-- ** actually layouts +-- +-- $layouts +-- +-- currently there are: +-- +-- * tall +-- +-- * floats +-- +-- * threeCol + +tall = renamed [Replace "tall"] + $ smartBorders + $ addTabs shrinkText myTabTheme + $ subLayout [] (smartBorders Simplest ||| Accordion) + $ limitWindows 12 + $ mySpacing 4 + $ ResizableTall 1 (5/100) (1/2) [] + +floats = renamed [Replace "floats"] + $ smartBorders + $ limitWindows 20 + $ simplestFloat + +threeCol = renamed [Replace "threeCol"] + $ smartBorders + $ addTabs shrinkText myTabTheme + $ subLayout [] (smartBorders Simplest ||| Accordion) + $ limitWindows 7 + $ mySpacing 4 + $ ThreeColMid 1 (3/100) (1/2) + +-- | setting colors for tabs layout and tabs sublayout. +myTabTheme = def + { fontName = (myFonts !! 0) + , activeColor = myColor "gray4" + , inactiveColor = myColor "gray0" + , activeBorderColor = myColor "gray4" + , inactiveBorderColor = myColor "gray0" + , activeTextColor = myColor "bg" + , inactiveTextColor = myColor "fg" + } + +-- ** layout hook + +-- $layoutHook +-- +-- putting it all together with some stuff +myLayoutHook = avoidStruts + $ mouseResize + $ BW.boringWindows + $ windowNavigation + $ windowArrange + $ T.toggleLayouts floats + $ mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout + where + myDefaultLayout = withBorder myBorderWidth tall + ||| withBorder myBorderWidth threeCol + +-- * show wm name hook + +-- | theme for showWName which prints current workspace +-- when you change workspaces. +myShowWNameTheme :: SWNConfig +myShowWNameTheme = def + { swn_font = (myFonts !! 1) + , swn_fade = 0.7 + , swn_bgcolor = myColor "bg" + , swn_color = myColor "fg" + } + +-- * workspaces +-- +-- $workspaces +-- +-- here are some helper functions to deal with workspaces. +-- +-- actual workspace list is in "LaNinpreConfig". + +-- | workspace indices to use with hotkeys +myWorkspaceIndices = M.fromList $ zipWith (,) myWorkspaces [1..] + +-- ** clickable workspace wrapper +-- +-- $clickable +-- +-- normal variant +-- +-- > clickable ws = "<action=xdotool key super+"++show i++">"++ws++"</action>" +-- > where i = fromJust $ M.lookup ws myWorkspaceIndices + +-- | provides option to click workspaces to switch to them. +-- this is handled by @UnsafeStdinReader@ in xmobar config. +clickable ws = "<fn=3><action=xdotool key super+"++show i++">"++ws++"</action></fn>" + where i = fromJust $ M.lookup ws myWorkspaceIndices + +-- * keybindings + +-- | keybindings list +-- +-- there's no way to document it using haddock, i guess... +myKeys :: [(String, X ())] +myKeys = + [ ("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-r", spawn "dmenu_run -i -p \"Run: \"") -- Dmenu + + -- Other Dmenu Prompts + -- In Xmonad and many tiling window managers, M-p is the default keybinding to + -- launch dmenu_run, so I've decided to use M-p plus KEY for these dmenu scripts. + , ("M-p p", spawn "passmenu") -- passmenu + , ("M-p c", spawn "dm-colpick") -- pick color from our scheme + , ("M-p e", spawn "dm-confedit") -- edit config files + , ("M-p i", spawn "dm-maim") -- screenshots (images) + , ("M-p k", spawn "dm-kill") -- kill processes + , ("M-p m", spawn "dm-man") -- manpages + , ("M-p q", spawn "dm-logout") -- logout menu + , ("M-p s", spawn "dm-websearch") -- search various search engines + , ("M-p h", spawn "dm-hub") -- hub of all scripts to choose one + + -- Useful programs to have a keybinding for launch + , ("M-<Return>", spawn (myTerminal)) + , ("M-e", spawn (myFileMgr)) + , ("M-w", spawn (myBrowser)) + , ("M-i", spawn (myTerminal + ++ " --class alacritty,amfora -e " + ++ myGeminiClient)) + -- 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 + -- Shifts focused window to next ws + , ("M-S-<KP_Add>", shiftTo Next nonNSP >> moveTo Next nonNSP) + -- Shifts focused window to prev ws + , ("M-S-<KP_Subtract>", shiftTo Prev nonNSP >> moveTo Prev nonNSP) + + -- 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) + , ("C-M1-j", decWindowSpacing 4) -- Decrease window spacing + , ("C-M1-k", incWindowSpacing 4) -- Increase window spacing + , ("C-M1-h", decScreenSpacing 4) -- Decrease screen spacing + , ("C-M1-l", incScreenSpacing 4) -- Increase screen spacing + + -- Grid Select (MOD-g followed by a key) + , ("M-g g", spawnSelected' myAppGrid) -- grid select favorite apps + , ("M-g t", goToSelected $ myGridConfig myColorizer) -- goto selected window + , ("M-g b", bringSelected $ myGridConfig myColorizer) -- bring selected window + + -- Windows navigation + , ("M-m", windows W.focusMaster) -- Move focus to the master window + , ("M-j", BW.focusDown) -- Move focus to the next window + , ("M1-<Tab>", BW.focusDown) -- legacy keybinding + , ("M-k", BW.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-b", sendMessage (MT.Toggle NBFULL)) + , ("M-<Space>", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) -- Toggles noborder/full + + -- Increase/decrease windows in the master pane or the stack + , ("M-S-<Up>", sendMessage (IncMasterN 1)) -- Increase # of clients master pane + , ("M-S-<Down>", sendMessage (IncMasterN (-1))) -- Decrease # of clients master pane + , ("M-C-<Up>", increaseLimit) -- Increase # of windows + , ("M-C-<Down>", decreaseLimit) -- Decrease # 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) -- Expand 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-<Space>", toSubl NextLayout) + , ("M-C-.", onGroup W.focusUp') -- Switch focus to next tab + , ("M-C-,", onGroup W.focusDown') -- Switch focus to prev tab + + -- Scratchpads + -- Toggle show/hide these programs. They run on a hidden workspace. + -- When you toggle them to show, it brings them to your current workspace. + -- Toggle them to hide and it sends them back to hidden workspace (NSP). + , ("M-s t", namedScratchpadAction myScratchPads "terminal") + , ("M-s m", namedScratchpadAction myScratchPads "mocp") + , ("M-s c", namedScratchpadAction myScratchPads "calculator") + , ("M-s v", namedScratchpadAction myScratchPads "mpvfloat" ) + + -- Set wallpaper with 'feh'. Type 'SUPER+F1' to launch sxiv in the wallpapers directory. + -- Then in sxiv, type 'C-x w' to set the wallpaper that you choose. + , ("M-<F1>", spawn "sxiv -r -q -t -o ~/Pictures/wallpapers/*") + , ("M-<F2>", spawn "/bin/ls ~/Pictures/wallpapers | shuf -n 1 \ + \| xargs xwallpaper --stretch") + + -- pana e nimi sewi + , ("M-<F7>", spawn "nimi_sewi") + + -- Controls for mocp music player (SUPER-u followed by a key) + , ("M-u p", spawn (myMocp ++ " --play")) + , ("M-u l", spawn (myMocp ++ " --next")) + , ("M-u h", spawn (myMocp ++ " --previous")) + , ("M-u <Space>", spawn (myMocp ++ " --toggle-pause")) + + -- Multimedia Keys + , ("<XF86AudioPlay>", spawn (myMocp ++ " --toggle-pause")) + , ("<XF86AudioPrev>", spawn (myMocp ++ " --previous")) + , ("<XF86AudioNext>", spawn (myMocp ++ " --next")) + , ("<XF86AudioMute>", spawn (myMocp ++ " -v 0")) + , ("<XF86AudioLowerVolume>", spawn (myMocp ++ " -v -1")) + , ("<XF86AudioRaiseVolume>", spawn (myMocp ++ " -v +1")) + , ("<XF86HomePage>", spawn "brave https://aaoth.xyz") + , ("<XF86Search>", spawn "dm-websearch") + , ("<XF86Mail>", runOrRaise "geary" (resource =? "geary")) + , ("<XF86Calculator>", namedScratchpadAction myScratchPads "calculator") + , ("<XF86Sleep>", spawn "dm-logout") + ] + -- 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 + xmproc <- spawnPipe "xmobar ~/.xmonad/xmobar/xmobarrc" + -- the xmonad, ya know...what the wm is named after! + xmonad $ ewmh def + { manageHook = myManageHook <+> manageDocks + , handleEventHook = docksEventHook + , modMask = myModMask + , terminal = myTerminal + , startupHook = myStartupHook + , layoutHook = showWName' myShowWNameTheme $ myLayoutHook + , workspaces = myWorkspaces + , borderWidth = myBorderWidth + , normalBorderColor = myNormColor + , focusedBorderColor = myFocusColor + , logHook = dynamicLogWithPP + $ namedScratchpadFilterOutWorkspacePP + $ xmobarPP + { ppOutput = hPutStrLn xmproc + , ppCurrent = xmobarColor (myColor "green-bright") "" + . wrap "<fn=3>" "</fn>" -- toki pona + . wrap "[" "]" + -- . wrap " " " " -- normal + , ppVisible = xmobarColor (myColor "green-bright") "" . clickable + , ppHidden = xmobarColor (myColor "blue-bright") "" + . wrap "" "'" + . clickable + , ppHiddenNoWindows = xmobarColor (myColor "gray2") "" . clickable + --, ppHiddenNoWindows = myHiddenNoWindows + , ppTitle = xmobarColor (myColor "gray4") "" . shorten 60 + , ppSep = xmobarColor (myColor "gray3") "" " | " + , ppWsSep = " " + , ppUrgent = xmobarColor (myColor "yellow") "" . wrap "!" "!" + , ppExtras = [myWindowCountLogger] + , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t] + } + } `additionalKeysP` myKeys +
A xpm/la_ninpre.xpm

@@ -0,0 +1,36 @@

+/* XPM */ +/* la-ninpre fungus xpm version */ +static char * la_ninpre_xpm[] = { +"24 24 8 1", +" c None", +". c #19191A", +"@ c #C74444", +"+ c #ED7C68", +"# c #F9A776", +"$ c #ECECF0", +"% c #CECED2", +"& c #88888F", +" ", +" .... ", +" ...+@+@... ", +" ..#@#@$%@@@@.. ", +" .@+@%@+@@@@%@@@. ", +" .%#@$@+$%@$@@@$%@. ", +" .@#@$@#@@@@@%@@@@@@. ", +" .%@+@+@@%$@@@@$%@@@. ", +" .%@%@$@@@$%@@@@@@. ", +" ...+@%@+@@@@%... ", +" .......... ", +" .&&%%. ", +" .&$%%. ", +" .$%$%. ", +" .$$$%%%. ", +" .&$%$%&. ", +" ...... ", +" .&%%&. ", +" ..%%%%.. ", +" .&&....&&. ", +" .&$&$%&%&. ", +" .%$%$%%. ", +" ..%%%%.. ", +" .... "};