]> Git — Sourcephile - julm/julm-nix.git/blob - home-manager/profiles/xmonad/xmonad.hs
+user/updatability(nixos-unstable): pin latest
[julm/julm-nix.git] / home-manager / profiles / xmonad / xmonad.hs
1 {-# LANGUAGE GHC2024 #-}
2 {-# OPTIONS_GHC -Wall #-}
3 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
4 import Data.Default
5 import qualified Data.Char as Char
6 import Data.List as List
7 import Data.Functor ((<&>))
8 import Data.Ratio
9 import System.Exit
10 import qualified Data.Map as Map
11 import Control.Arrow (first)
12
13 -- import XMonad.Actions.DwmPromote
14 -- import XMonad.Actions.Warp
15 -- import XMonad.Layout.Maximize
16 -- import XMonad.Layout.Monitor
17 -- import XMonad.Layout.ResizableTile
18 -- import XMonad.Layout.TabBarDecoration
19 -- import XMonad.Util.EZConfig
20 -- import XMonad.Util.EZConfig(additionalKeys)
21 -- import XMonad.Util.WorkspaceCompare
22 import XMonad hiding ((|||))
23 import XMonad.Actions.CopyWindow
24 import XMonad.Actions.CycleWS
25 import XMonad.Actions.SwapWorkspaces
26 import XMonad.Actions.UpdatePointer
27 import XMonad.Config.Azerty
28 import XMonad.Hooks.DynamicLog
29 import XMonad.Hooks.EwmhDesktops
30 import XMonad.Hooks.ManageDocks
31 import XMonad.Hooks.ManageHelpers
32 import XMonad.Hooks.RefocusLast
33 import XMonad.Hooks.Rescreen
34 import XMonad.Hooks.SetWMName
35 import XMonad.Hooks.StatusBar
36 import XMonad.Hooks.UrgencyHook
37 import XMonad.Layout.Columns
38 import XMonad.Layout.Fullscreen
39 import XMonad.Layout.Grid
40 import XMonad.Layout.LayoutCombinators
41 import XMonad.Layout.Magnifier
42 import XMonad.Layout.MultiToggle
43 import XMonad.Layout.MultiToggle.Instances
44 import XMonad.Layout.NoBorders
45 import XMonad.Layout.ResizableTile
46 import XMonad.Layout.Spiral
47 import XMonad.Layout.Tabbed
48 import XMonad.Layout.ThreeColumns
49 import XMonad.Layout.WindowNavigation
50 import XMonad.ManageHook
51 import XMonad.Operations (unGrab)
52 import XMonad.Prompt
53 import XMonad.Prompt.FuzzyMatch
54 import XMonad.Prompt.Pass
55 import XMonad.Prompt.Window
56 import XMonad.Util.NamedScratchpad
57 import XMonad.Util.SpawnOnce
58 import qualified XMonad.StackSet as W
59
60 main = xmonad $
61 withUrgencyHook NoUrgencyHook $
62 -- dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] } $
63 --addAfterRescreenHook myAfterRescreenHook $
64 addRandrChangeHook (spawnExec "autorandr --change") $
65 dynamicSBs barSpawner $
66 docks $
67 setEwmhActivateHook doAskUrgent $
68 ewmhFullscreen $
69 ewmh $
70 azertyConfig
71 { borderWidth = 1
72 , focusFollowsMouse = True
73 , focusedBorderColor = "#00b10b"
74 , handleEventHook = handleEventHook def
75 , keys = \conf@XConfig{XMonad.modMask} ->
76 Map.fromList $
77 let xK_XF86Backward = 0x1008ff26
78 xK_XF86Forward = 0x1008ff27 in
79 [
80 -- Start a terminal
81 ((modMask, xK_Return), spawnExec $ XMonad.terminal conf)
82 -- Launch a program
83 , ((modMask, xK_Menu), spawnCommand)
84 , ((modMask, xK_space), spawnCommand)
85 -- Browse the filesystem
86 , ((modMask, xK_BackSpace), spawnExec "systemd-run --user --unit=app-caja@$RANDOM -p CollectMode=inactive-or-failed caja")
87
88 -- Lock the screen
89 , ((0, xK_Pause), unGrab >> spawnExec "loginctl lock-session \"$XDG_SESSION_ID\"")
90 , ((modMask, xK_Delete), unGrab >> spawnExec "loginctl lock-session \"$XDG_SESSION_ID\"")
91
92 -- Take a full screenshot
93 , ((0, xK_Print), spawn "mkdir -p ~/Images/screenshots && scrot --quality 42 ~/Images/screenshots/'%Y-%m-%d_%H-%M-%S.png' && caja ~/Images/screenshots")
94 -- Take a selective screenshot
95 , ((modMask, xK_Print), spawn "select-screenshot")
96
97 -- Volume control
98 , ((0, 0x1008FF12), spawnExec "pactl -- set-sink-mute @DEFAULT_SINK@ toggle") -- XF88AudioMute
99 , ((0, 0x1008FF11), spawnExec "pactl -- set-sink-volume @DEFAULT_SINK@ -5%") -- XF86AudioLowerVolume
100 , ((0, 0x1008FF13), spawnExec "pactl -- set-sink-volume @DEFAULT_SINK@ +5%") -- XF86AudioRaiseVolume
101 -- Audio previous
102 -- , ((0, 0x1008FF16), spawnExec "")
103 -- Play/pause
104 -- , ((0, 0x1008FF14), spawnExec "")
105 -- Audio next
106 -- , ((0, 0x1008FF17), spawnExec "")
107 -- Eject CD tray
108 -- , ((0, 0x1008FF2C), spawnExec "eject -T")
109
110 -- Close focused window.
111 , ((modMask, xK_Escape), kill)
112
113 -- Clipboard
114 , ((modMask, xK_c), spawnExec "clipster --select --primary")
115
116 -- Temporarily maximize a window
117 , ((modMask, xK_f), sendMessage $ XMonad.Layout.MultiToggle.Toggle FULL)
118 -- , ((modMask, xK_f), withFocused (sendMessage . maximizeRestore))
119
120 -- Cycle through the available layout algorithms
121 , ((modMask, 0x13bd), sendMessage NextLayout) -- oe (²)
122 , ((modMask, xK_ampersand), sendMessage $ JumpToLayout "ResizableTall") -- & (1)
123 , ((modMask, xK_eacute), sendMessage $ JumpToLayout "Mirror ResizableTall") -- é (2)
124 , ((modMask, xK_quotedbl), sendMessage $ JumpToLayout "Tabbed Simplest") -- ' (3)
125 , ((modMask, xK_apostrophe), sendMessage $ JumpToLayout "Magnifier Grid") -- " (4)
126 , ((modMask, xK_parenleft), sendMessage $ JumpToLayout "Spiral") -- ( (5)
127 , ((modMask, xK_minus), sendMessage $ JumpToLayout "Full") -- - (6)
128 , ((modMask, xK_egrave), sendMessage $ JumpToLayout "ThreeCol") -- è (7)
129 , ((modMask, xK_underscore), sendMessage $ JumpToLayout "Columns") -- _ (8)
130
131 -- Reset the layouts on the current workspace to default
132 -- , ((modMask .|. shiftMask, xK_space), setLayout $ XMonad.layoutHook conf)
133
134 -- Resize viewed windows to the correct size.
135 , ((modMask, xK_n), refresh)
136
137 -- Move focus to the master window
138 , ((modMask .|. shiftMask, xK_exclam), windows W.focusMaster)
139 -- Swap the focused window and the master window
140 , ((modMask, xK_exclam), windows W.swapMaster)
141
142 -- Swap the focused window with the next window.
143 --, ((modMask, xK_o), windows W.swapDown >> windows W.focusMaster)
144 -- Swap the focused window with the previous window.
145 , ((modMask, xK_m), windows W.swapUp >> windows W.focusMaster)
146
147 -- Move focus
148 , ((modMask, xK_h), sendMessage $ Go L)
149 , ((modMask, xK_m), sendMessage $ Go R)
150 --, ((modMask, xK_i), sendMessage $ Go U)
151 --, ((modMask, xK_k), sendMessage $ Go D)
152 , ((modMask, xK_i), windows W.focusUp)
153 , ((modMask, xK_k), windows W.focusDown)
154 , ((modMask, xK_j), prevWS)
155 , ((modMask, xK_l), nextWS)
156 , ((modMask, xK_Left), windows W.focusUp)
157 , ((modMask, xK_Right), windows W.focusDown)
158 --, ((modMask, xK_Left), onGroup W.focusUp')
159 --, ((modMask, xK_Right), onGroup W.focusDown')
160 , ((modMask, xK_Up), sendMessage $ Go U)
161 , ((modMask, xK_Down), sendMessage $ Go D)
162
163 -- Move windows
164 , ((modMask .|. shiftMask, xK_h), sendMessage MoveLeft)
165 , ((modMask .|. shiftMask, xK_m), sendMessage MoveRight)
166 , ((modMask .|. controlMask, xK_h), sendMessage MoveLeft)
167 , ((modMask .|. controlMask, xK_m), sendMessage MoveRight)
168 , ((modMask .|. controlMask, xK_i), sendMessage MoveUp)
169 , ((modMask .|. controlMask, xK_k), sendMessage MoveDown)
170 , ((modMask .|. controlMask, xK_j), shiftToPrev >> prevWS)
171 , ((modMask .|. controlMask, xK_l), shiftToNext >> nextWS)
172
173 -- Resize windows
174 , ((modMask .|. shiftMask, xK_l), sendMessage HorizontalExpand)
175 , ((modMask .|. shiftMask, xK_j), sendMessage HorizontalShrink)
176 , ((modMask .|. shiftMask, xK_i), sendMessage VerticalExpand)
177 , ((modMask .|. shiftMask, xK_k), sendMessage VerticalShrink)
178
179 -- Push window back into tiling.
180 , ((modMask, xK_t), withFocused $ windows . W.sink)
181
182 -- Change the number of windows in the master area
183 , ((modMask, xK_Up), sendMessage $ IncMasterN 1)
184 , ((modMask, xK_Down), sendMessage $ IncMasterN (-1))
185
186 -- Toggle the status bar gap.
187 , ((modMask, xK_b), sendMessage ToggleStruts)
188
189 -- Quit xmonad
190 , ((modMask .|. shiftMask, xK_End), io exitSuccess)
191 -- Restart xmonad
192 , ((modMask, xK_End), restart "xmonad" True)
193
194 , ((modMask, xK_p), passPrompt promptConfig)
195 , ((modMask .|. controlMask, xK_p), passGeneratePrompt promptConfig)
196 , ((modMask .|. controlMask .|. shiftMask, xK_p), passRemovePrompt promptConfig)
197 , ((modMask, xK_Tab), windowMultiPrompt promptConfig [(Goto, allWindows), (Goto, wsWindows)])
198
199 -- Jump to latest viewed workspace
200 , ((modMask, xK_less), toggleWS' ["NSP"])
201
202 -- Workspace management
203 -- XF86Back: Switch to previous workspace
204 , ((0, xK_XF86Backward), prevWS)
205 , ((modMask, xK_Page_Up), prevWS)
206 -- Switch to next workspace
207 , ((0, xK_XF86Forward), nextWS)
208 , ((modMask, xK_Page_Down), nextWS)
209 -- XF86Back: Move the current client to the previous workspace and go there
210 , ((modMask, xK_XF86Backward), shiftToPrev >> prevWS)
211 -- Move the current client to the next workspace and go there
212 , ((modMask, xK_XF86Forward), shiftToNext >> nextWS)
213 -- Switch to previous workspace
214 -- Switch to next workspace
215 {-
216 -- Move the current client to the previous workspace
217 , ((0 .|. shiftMask , xK_XF86Backward), shiftToPrev )
218 -- Move the current client to the next workspace
219 , ((0 .|. shiftMask , xK_XF86Forward), shiftToNext )
220 -}
221
222 -- Toggle copying window on all workspaces (sticky window)
223 , ((modMask, xK_s), do
224 copies <- wsContainingCopies -- NOTE: consider only hidden workspaces
225 case copies of
226 [] -> windows copyToAll
227 _ -> killAllOtherCopies
228 )
229
230 -- Resize the master area
231 --, ((modMask, xK_Left), sendMessage Shrink)
232 --, ((modMask, xK_Right), sendMessage Expand)
233 -- Resize windows in ResizableTall mode
234 --, ((modMask .|. shiftMask, xK_Left), sendMessage MirrorShrink)
235 --, ((modMask .|. shiftMask, xK_Right), sendMessage MirrorExpand)
236 ] ++
237
238 -- Dynamic scratchpads
239 (mconcat
240 [ [ ((modMask .|. altMask .|. controlMask, key), withFocused $ toggleDynamicNSP name)
241 , ((modMask .|. altMask, key), dynamicNSPAction name)
242 ]
243 | (key, chr) <- zip [xK_a..] ['a'..'z']
244 , let name = [chr]
245 ]
246 ) ++
247
248 -- Named scratchpads
249 -- Note: those keybindings override dynamic scratchpads above
250 [ ((modMask .|. altMask, xK_b), namedScratchpadAction scratchpads "btop")
251 , ((modMask .|. altMask, xK_c), namedScratchpadAction scratchpads "中文")
252 , ((modMask .|. altMask, xK_d), namedScratchpadAction scratchpads "dino")
253 , ((modMask .|. altMask, xK_e), namedScratchpadAction scratchpads "english")
254 , ((modMask .|. altMask, xK_h), namedScratchpadAction scratchpads "htop")
255 , ((modMask .|. altMask, xK_m), namedScratchpadAction scratchpads "matrix")
256 , ((modMask .|. altMask, xK_n), namedScratchpadAction scratchpads "notes")
257 , ((modMask .|. altMask, xK_o), namedScratchpadAction scratchpads "concerns")
258 , ((modMask .|. altMask, xK_s), namedScratchpadAction scratchpads "signal")
259 , ((modMask .|. altMask, xK_v), namedScratchpadAction scratchpads "pavucontrol")
260 , ((modMask .|. altMask, xK_u), namedScratchpadAction scratchpads "umpv")
261 , ((modMask .|. altMask, xK_space), namedScratchpadAction scratchpads "terminal")
262 , ((modMask .|. altMask, xK_Return), namedScratchpadAction scratchpads "terminal")
263 , ((modMask .|. altMask, xK_BackSpace), resetFocusedNSP)
264 ] ++
265
266 -- mod-[F1..F9], Switch to workspace N
267 [ ((modMask, k), windows $ W.greedyView i)
268 | (i, k) <- zip (workspaces conf) [xK_F1 ..] ++
269 zip (workspaces conf) [xK_1 ..]
270 ] ++
271
272 -- mod-shift-[F1..F9], Move client to workspace N
273 [ ((modMask .|. shiftMask, k), windows $ W.shift i)
274 | (i, k) <- zip (workspaces conf) [xK_F1 ..] ++
275 zip (workspaces conf) [xK_1 ..]
276 ] ++
277
278 {- NOTE: with Xinerama
279 [((m .|. modMask, k), windows $ onCurrentScreen f i)
280 | (i, k) <- zip (workspaces' conf) [xK_F1 ..]
281 , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)] ]
282 -}
283
284 -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3
285 [ ((modMask, key), screenWorkspace sc >>= flip whenJust (windows . W.view))
286 | (key, sc) <- zip [xK_w, xK_e, xK_r] [0 ..]
287 ] ++
288
289 -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3
290 [ ((modMask .|. shiftMask, key), screenWorkspace sc >>= flip whenJust (windows . W.shift))
291 | (key, sc) <- zip [xK_w, xK_e, xK_r] [0 ..]
292 ] ++
293
294 -- mod-ctrl-[F1..F9], Swap workspace with workspace N
295 -- mod-ctrl-[1..9], Swap workspace with workspace N
296 [ ((modMask .|. controlMask, k), windows $ swapWithCurrent i)
297 | (i, k) <- zip (workspaces conf) [xK_F1 ..] ++
298 zip (workspaces conf) [xK_1 ..]
299 ]
300 {- NOTE: with Xinerama
301 [((modMask .|. controlMask, k), windows $ onCurrentScreen swapWithCurrent i)
302 | (i, k) <- zip (workspaces' conf) [xK_F1 ..] ]
303 -}
304 , layoutHook = smartBorders $
305 mkToggle (NOBORDERS ?? FULL ?? EOT) $ -- enable temporarily maximizing a window
306 avoidStruts $ -- prevents windows from overlapping dock windows
307 let tall = ResizableTall 1 (1%200) (8%13) [] in
308 windowNavigation $
309 -- addTabs shrinkText tabBar (subLayout [] Simplest (Columns 1 []))
310 Columns 1 []
311 ||| tabbed shrinkText tabConfig
312 ||| tall
313 ||| Mirror tall
314 ||| magnifiercz (13%10) Grid
315 ||| spiral (6%7)
316 ||| noBorders (fullscreenFull Full)
317 ||| ThreeColMid 1 (1%200) (1%2)
318 -- ||| Tall 1 (3/100) (1/2)
319 , manageHook = composeAll
320 -- [ , isFullscreen --> (doF W.focusDown <+> doFullFloat)
321 [ isFullscreen --> doFullFloat
322 , manageHook def
323 , manageDocks -- NOTE: do not tile dock windows
324 , namedScratchpadManageHook scratchpads
325 , resource =? "desktop_window" --> doIgnore
326 , className =? "Gimp" --> doFloat
327 , resource =? "gpicview" --> doSink
328 , className =? "mpv" --> doFloat
329 , className =? "ultrastardx" --> doSink
330 --, className =? "MPlayer" --> doShift "3:media" -- <+> doFloat
331 --, className =? "vlc" --> doShift "3:media"
332 , className =? "trayer" --> doIgnore
333 ]
334 , modMask = mod4Mask
335 , mouseBindings = \XConfig{XMonad.modMask} ->
336 Map.fromList
337 [
338 -- mod-button1, Set the window to floating mode and move by dragging
339 ((modMask, button1), floatMoveNoexclusive)
340
341 -- mod-button2, Raise the window to the top of the stack
342 , ((modMask, button2), \w -> focus w >> windows W.swapMaster)
343
344 -- mod-button3, Set the window to floating mode and resize by dragging
345 , ((modMask, button3), resizeNoexclusive)
346
347 , ((modMask, button4), \_ -> windows W.focusUp)
348 , ((modMask, button5), \_ -> windows W.focusDown)
349
350 -- Cycle through workspaces
351 , ((controlMask .|. modMask, button5), nextNonEmptyWS)
352 , ((controlMask .|. modMask, button4), prevNonEmptyWS)
353 ]
354 , normalBorderColor = "#7C7C7C"
355 , startupHook =
356 setWMName "XMonad"
357 <+> addExclusives [ [ name | NS{name} <- scratchpadsExclusive ] ]
358 <+> spawnExec "wmname XMonad"
359 <+> spawnExec "xrdb -all .Xresources"
360 <+> spawn "sleep 1 && xmodmap .Xmodmap"
361 <+> spawnExec "xset r rate 250 25"
362 <+> spawnExec "xinput --set-button-map 'Logitech USB Receiver Mouse' 1 2 3 4 5 6 7 2"
363 <+> spawnExec "xset b off"
364 <+> spawnExec "xhost local:root"
365 <+> spawnExec "setxkbmap -option keypad:pointerkeys"
366 -- Useful for programs launched by rofi
367 <+> spawnExec (unwords [ "systemctl --user import-environment"
368 , "DBUS_SESSION_BUS_ADDRESS"
369 , "GDK_PIXBUF_MODULE_FILE"
370 , "GIO_EXTRA_MODULES"
371 , "GLFW_IM_MODULE"
372 , "GNUPGHOME"
373 , "GTK2_RC_FILES"
374 , "GTK_A11Y"
375 , "GTK_IM_MODULE"
376 , "GTK_PATH"
377 , "LANG"
378 , "LD_LIBRARY_PATH" -- For sane and pipewire
379 , "LIBEXEC_PATH"
380 , "NIX_PROFILES" -- fcitx5 does not work without it…
381 , "PASSWORD_STORE_DIR"
382 , "PATH"
383 , "QTWEBKIT_PLUGIN_PATH"
384 , "QT_IM_MODULE"
385 , "QT_PLUGIN_PATH"
386 , "SPEECHD_CMD"
387 , "SSH_ASKPASS"
388 , "XCURSOR_PATH"
389 , "XMODIFIERS"
390 ])
391 -- <+> spawnOnce "exec arbtt-capture -r 60"
392 -- <+> spawnOnce "exec parcellite"
393 -- <+> spawnOnce "exec xautolock"
394 -- <+> spawnOnce "exec redshift-gtk -l -45.7800:1.9700 -t 6500:3700"
395 <+> spawnOnce "exec nm-applet"
396 , terminal = "$TERMINAL"
397 , workspaces = {- withScreens nScreens $ -}
398 {-["1:work","2:web","3:media"] ++-}
399 map show [1::Int .. 9]
400 , logHook = do
401 -- updatePointer (Relative 0.5 0.5)
402 refocusLastLogHook
403 nsHideOnFocusLoss scratchpadsExclusive
404 updatePointer (0.5, 0.5) (0, 0)
405 }
406 where
407 tabConfig = def
408 { activeBorderColor = "#7C7C7C"
409 , activeColor = "#000000"
410 , activeTextColor = "#00FF00"
411 , inactiveBorderColor = "#7C7C7C"
412 , inactiveColor = "#000000"
413 , inactiveTextColor = "#EEEEEE"
414 , fontName = "Hack 7"
415 }
416
417 spawnCommand = spawnExec "rofi -show run -no-disable-history -run-command \"bash -c 'systemd-run --user --unit=app-\\$(systemd-escape \\\"{cmd}\\\")@\\$RANDOM -p CollectMode=inactive-or-failed {cmd}'\""
418
419 barSpawner :: ScreenId -> X StatusBarConfig
420 barSpawner 0 = pure $ topXmobar <> traySB
421 --barSpawner 1 = pure $ xmobar1
422 barSpawner _ = pure $ topXmobar -- nothing on the rest of the screens
423
424 -- Display properties of the root window:
425 -- xprop -display $DISPLAY -root
426 topXmobar = statusBarPropTo "_XMONAD_XMOBAR0" "xmobar -x 0 ~/.config/xmonad/xmobar0.hs" (pure topPP)
427 where
428 topPP =
429 xmobarPP
430 { ppCurrent = xmobarColor "black" "#CCCCCC"
431 , ppHidden = xmobarColor "#CCCCCC" "black"
432 , ppHiddenNoWindows = xmobarColor "#606060" "black"
433 , ppLayout = \s -> xmobarColor "black" "#606060" $
434 case s of
435 "Columns" -> " \" "
436 "ResizableTall" -> " | "
437 "Mirror ResizableTall" -> " - "
438 "Tabbed Simplest" -> " + "
439 "Magnifier Grid" -> " ~ "
440 "Spiral" -> " @ "
441 "Full" -> " O "
442 "ThreeCol" -> " # "
443 _ -> s
444 , ppSep = " "
445 , ppTitle = xmobarColor "white" "black" . shorten 50
446 , ppUrgent = xmobarColor "yellow" "black"
447 , ppWsSep = " "
448 }
449
450 traySB :: StatusBarConfig
451 traySB =
452 statusBarGeneric
453 ( List.unwords
454 [ "trayer"
455 , "--align right"
456 , "--distance 0,0"
457 , "--distancefrom top,right"
458 , "--edge top"
459 , "--expand true"
460 , "--height 16"
461 , "--monitor primary"
462 , "--tint 0x000000"
463 , "--iconspacing 0"
464 , "--transparent true"
465 , "--widthtype request"
466 , "-l"
467 ]
468 )
469 mempty
470
471 nextNonEmptyWS _ = moveTo Next (WSIs ((not .) <$> isWindowSpaceVisible))
472 prevNonEmptyWS _ = moveTo Prev (WSIs ((not .) <$> isWindowSpaceVisible))
473
474 isWindowSpaceVisible :: X (WindowSpace -> Bool)
475 isWindowSpaceVisible = do
476 vs <- gets (map (W.tag . W.workspace) . W.visible . windowset)
477 return (\w -> W.tag w `elem` vs)
478
479 spawnExec s = spawn $ List.unwords $ [ "exec" ] <> systemdCat <> [ s ]
480 systemdCat = [ "systemd-cat" , "--priority=info", "--stderr-priority=warning", "--level-prefix=false" , "--" ]
481
482 promptConfig :: XPConfig
483 promptConfig = def
484 { font = "xft:monospace-"<>show fontSize
485 , bgColor = "black"
486 , fgColor = "grey"
487 , bgHLight = "green"
488 , fgHLight = "#000000"
489 , borderColor = "darkgreen"
490 , promptBorderWidth = 1
491 , promptKeymap = promptKeyMap
492 , position = CenteredAt { xpCenterY = 0.3, xpWidth = 0.5 }
493 , height = fontSize + 11
494 , historySize = 16
495 , historyFilter = id
496 , defaultText = ""
497 , autoComplete = Nothing -- Just 500000 -- nanoseconds
498 , showCompletionOnTab = False
499 , completionKey = (0, xK_Down)
500 , prevCompletionKey = (0, xK_Up)
501 , searchPredicate = fuzzyMatch -- isPrefixOf
502 , sorter = fuzzySort
503 , defaultPrompter = const ""
504 , alwaysHighlight = True
505 , maxComplRows = Just 10
506 , maxComplColumns = Just 1
507 , changeModeKey = xK_twosuperior
508 }
509 where
510 fontSize = 11
511
512 promptKeyMap :: Map.Map (KeyMask,KeySym) (XP ())
513 promptKeyMap = Map.fromList $
514 List.map (first $ (,) controlMask) -- control + <key>
515 [ (xK_z, killBefore) -- kill line backwards
516 , (xK_k, killAfter) -- kill line forwards
517 , (xK_u, killBefore) -- kill line backwards
518 , (xK_a, startOfLine) -- move to the beginning of the line
519 , (xK_e, endOfLine) -- move to the end of the line
520 , (xK_m, deleteString Next) -- delete a character forward
521 , (xK_b, moveCursor Prev) -- move cursor forward
522 , (xK_f, moveCursor Next) -- move cursor backward
523 , (xK_BackSpace, killWord Prev) -- kill the previous word
524 , (xK_y, pasteString) -- paste a string
525 , (xK_g, quit) -- quit out of prompt
526 , (xK_bracketleft, quit)
527 ]
528 ++
529 List.map (first $ (,) altMask) -- meta key + <key>
530 [ (xK_BackSpace, killWord Prev) -- kill the prev word
531 , (xK_f, moveWord Next) -- move a word forward
532 , (xK_b, moveWord Prev) -- move a word backward
533 , (xK_d, killWord Next) -- kill the next word
534 , (xK_n, moveHistory W.focusUp') -- move up through history
535 , (xK_p, moveHistory W.focusDown') -- move down through history
536 ]
537 ++
538 List.map (first $ (,) 0) -- <key>
539 [ (xK_Return, setSuccess True >> setDone True)
540 , (xK_KP_Enter, setSuccess True >> setDone True)
541 , (xK_BackSpace, deleteString Prev)
542 , (xK_Delete, deleteString Next)
543 , (xK_Left, moveCursor Prev)
544 , (xK_Right, moveCursor Next)
545 , (xK_Home, startOfLine)
546 , (xK_End, endOfLine)
547 , (xK_Down, moveHistory W.focusUp')
548 , (xK_Up, moveHistory W.focusDown')
549 , (xK_Escape, quit)
550 ]
551
552 altMask :: KeyMask
553 altMask = mod1Mask
554
555 -- HowTo(develop): use xprop to see window properties to query them
556 scratchpads =
557 scratchpadsExclusive <>
558 scratchpadsInclusive
559
560 scratchpadsExclusive =
561 [ NS { name = "btop", cmd = "$TERMINAL --title=btop -e btop", query = title =? "btop", hook }
562 , NS { name = "concerns", cmd = "$TERMINAL --title=concerns -e sh -c 'cd $HOME/work/sourcephile && vi Concerns.md'", query = title =? "concerns", hook }
563 , NS { name = "dino", cmd = "dino", query = className =? "dino", hook }
564 , NS { name = "english", cmd = "$TERMINAL --title=english -e sh -c 'cd $HOME/files/notes/english && vi vocabulary.org'", query = title =? "english", hook }
565 , NS { name = "htop", cmd = "$TERMINAL --title=htop -e htop", query = title =? "htop", hook }
566 , NS { name = "matrix", cmd = "element-desktop", query = className =? "Element", hook }
567 , NS { name = "notes", cmd = "$TERMINAL --title=notes -e sh -c 'cd $HOME/files/notes && vi notes.md'", query = title =? "notes", hook }
568 , NS { name = "pavucontrol", cmd = "pavucontrol", query = className =? "pavucontrol", hook }
569 , NS { name = "signal", cmd = "signal-desktop", query = className =? "Signal", hook }
570 , NS { name = "terminal", cmd = "$TERMINAL --title=scratch-term", query = title =? "scratch-term", hook }
571 , NS { name = "中文", cmd = "$TERMINAL --title=中文 -e sh -c 'cd $HOME/files/notes/中文 && vi Vocabulary.hs'", query = title =? "中文", hook }
572 ]
573 <&> \ns ->
574 ns
575 { cmd = mconcat
576 [ "sh -c 'exec systemd-run --user"
577 , " -p CollectMode=inactive-or-failed"
578 , " --unit=app-" <> cmd ns
579 , " " <> cmd ns
580 , "'"
581 ]
582 }
583 where hook = customFloating (W.RationalRect (1/2) (0) (1/2) (1))
584
585 scratchpadsInclusive =
586 [ NS { name = "umpv", cmd = "umpv", query = className =? "mpv", hook }
587 ]
588 where hook = customFloating (W.RationalRect (0) (0) (0) (0))