Assuming you use XMonad.Util.EZConfig
to configure your key mappings, this code allows you to print those mappings in a nice format and let them be visualized in multiple ways.
Starting from the latest darcs template xmonad.hs, but the key map configuration already replaced with XMonad.Util.EZConfig, I need the following imports extra imports:
import Data.Foldable
import qualified Data.List as L
This is the code containing the types used for formatting the input, and the actual formatting code.
data KeyMapCategory = MkCat { name :: String, mappings :: [ KeyMapKey ] }
unwrapCategory :: KeyMapCategory -> [ ( String, X () )]
unwrapCategory MkCat { mappings = m } = map unwrapKey m
data KeyMapKey = MkKey { binding :: String, action :: X (), catDescription :: String }
unwrapKey :: KeyMapKey -> ( String, X () )
unwrapKey MkKey { binding = b, action = a } = ( b, a )
categoryListFormat :: [ KeyMapCategory ] -> String
categoryListFormat = L.intercalate "\n\n\n" . map formatCategory
where
formatCategory MkCat { mappings = m, name = n } = L.intercalate "\n" $ n : "" : map formatBinding m
formatBinding MkKey { binding = b, catDescription = d } = L.intercalate "\n" [ b, d ]
categoryTextFormat :: [ KeyMapCategory ] -> String
categoryTextFormat = L.intercalate "\n\n" . map formatCategory
where
formatCategory MkCat { mappings = m, name = n } = L.intercalate "\n" $ n : map (formatBinding width) m
where width = foldl max 0 $ map (length . binding) m
formatBinding width MkKey { binding = b, catDescription = d } = padRight width b ++ " : " ++ d
padRight width str = if length str < width then padRight width (str ++ " ") else str
Now the key mapping can be defined as follows:
myKeyMap :: [ KeyMapCategory ]
myKeyMap =
[ MkCat "App launching"
[ MkKey "M-S-<Return>"
(spawn myTerminal)
"Launch a terminal"
, MkKey "M-p"
(spawn "rofi -show drun")
"Launch rofi"
-- etc, more keys in a category...
]
-- etc, more categories...
]
I came up with three ways to display this:
- In yad as a list
- In yad as text
- In rofi as text
These are the bindings I made for them:
, MkKey "M-S-/"
(spawn $ unwords
["yad"
, "--list"
, "--no-markup"
, "--column Binding"
, "--column Action"
, "--title=Keybindings"
, "--geometry=500x775"
, "--no-buttons"
, "--undecorated"
, "--text=<<EOF\n" ++ categoryListFormat myKeyMap ++ "\nEOF"
])
"Show the key bindings (list)"
, MkKey "M-C-S-/"
(spawn $ unwords
["yad"
, "--text-info"
, "--no-markup"
, "--title=Keybindings"
, "--geometry=650x825"
, "--no-buttons"
, "--undecorated"
, "--fontname=\"Source Code Pro 12\""
, "--text=<<EOF\n" ++ categoryTextFormat myKeyMap ++ "\nEOF"
])
"Show the key bindings (textual)"
, MkKey "M-C-/"
(spawn $ "cat <<EOF | rofi -p Bindings -columns 1 -dmenu\n" ++ categoryTextFormat myKeyMap ++ "\nEOF")
"Show the key bindings (rofi)"
Now all that needs to be done is actually convert the new type of my myKeyMap
to something xmonad understands: Change
} `additionalKeysP` myKeyMap
to
} `additionalKeysP` L.concatMap unwrapCategory myKeyMap