Want A List Of Your Keybindings? Write A Shell Script!

DistroTube
233 followers
Oct 25, 2024
one of my favorite kinds of videos to
make is where i solve a real world
problem
through the use of shell scripting
because a lot of
linux users especially those of you that
are new to linux
shell scripting seems like it's
something that's really hard it's
complicated you know you got
to learn a ton of stuff to get this
stuff to work but really
once you start playing around a little
bit with the terminal and the command
line
you can quickly figure out a lot of the
basic command line utilities that are
needed to create these shell scripts
and you can really start solving a lot
of problems through the use of shell
scripting so what is the problem that
i'm gonna solve today
well it involves your key bindings and
you're telling window managers a lot of
people want an easy way to bring up a
list of all their key bindings for their
tiling window manager
and the reason people ask about this all
the time is because there's one tiling
window manager that really gets this
right
the awesome tiling window manager the
awesome window manager
you hold the super key and a window pops
up and it lists
all your key bindings for the awesome
window manager
and now everybody that runs all these
other tiling window managers
want that same feature in their window
manager but of course these other window
managers don't have that feature
well you know what we can kind of create
something with a simple shell script so
let me switch over to my desktop
and today i'm running the xmonet window
manager and i've already pulled up my
xmonet config
here inside doom emacs because what i
want to do is i want to be able to grab
all the key bindings and the commands
they run from my exmonet config
so what i'm going to do is i'm actually
just going to page down here
actually i went a little too far this is
my key bindings it's in this statement
that says my keys equals and then
i've got a very long list of key
bindings here in xml net
what i would like to do is find some way
to pull all of these key bindings out
you know just basically everything that
was in that my keys block i
i don't need the rest of the config
obviously printed out because we just
want a window that pops up that shows us
the key bindings
so what's the best way to do this i
don't know the best way i'm not a
professional programmer you know i just
do this as a hobby
but i know that sid has the ability
to give you a number of lines from
well you give it a starting statement
and an ending statement and it pulls out
all the lines from
each of those statements so what i'm
going to do is i'm just going to create
some special comments here now
comments in haskell begin with dashes
two dashes so i'm going to do
dash dash space and i'm just going to do
start underscore
keys all caps and then i'm going to
escape i'm going to page down
to the end of my key bindings here and
let's go back up
that was the end of the key bindings and
then i'm going to just go ahead and
create one more comment here i'm going
to do dash
dash space and underscore keys
and escape so let me go ahead and save
this to
my xmonet.hs config file so
i went ahead and did colon w to write
and i'm going to do
a key binding i have for org babble
tangle here inside
doom emacs and then now that i've saved
that
what i'm going to do is i'm going to
open a terminal let's uh go ahead and
zoom way in
here in the terminal as well so you guys
can see this what i'm going to do is i'm
going to run the command
sid dash in and then inside single
quotes i'm going to do slash
start underscore keys because that's the
the starting
comment that we wanted so i want to pull
all lines starting with start
underscore keys and then slash comma
slash and then in
underscore keys and then the ending
slash and then the command i want to run
on this i want to run the print command
p and then we need to give it the path
to my exmonad config
so that would be in my home directory at
slash.xmo.net because it's a hidden
directory slash and then
xmonet.hs and that prints out
let me make this full screen that prints
out every line between
uh start underscore keys and in
underscore keys now of course many of
these
lines don't we don't need necessarily
because some of these are just comments
really some of them are useless comments
we could get rid of some of that
we could also get rid of some of the
extra notation
and syntax and things we could clean
this up a little bit and that's what i'm
going to do
so what i'm going to do is i'm going to
up arrow and i'm going to run the same
sed command
you know to get all of these lines from
start keys to end keys and then i'm
going to pipe it
into grip because grip will allow us to
do some interesting stuff here for
example if i wanted to
i only want to get the lines that
actually have the actual key bindings
and the actual lines that have key
bindings
looks like all of them start with comma
space
opening parentheses and then a double
quote so why don't i just grip
that so we do prep and then inside
single quotes
comma space opening parenthesis double
quote
and now when i run that it's a lot
cleaner right because all of those
comments which were lines that started
with dash dash
are no longer outputted here well
actually looking at it that's not
entirely true we do have some commented
lines that were returned because some of
the commented lines that started with
dash dash also had the
the string comma space opening
parentheses double quotes because these
were
key bindings that i've disabled by
commenting them out
i don't want those returned if i'm not
currently using the key binding you know
it's a commented key binding i don't
want that to be listed either so i'm
going to up
arrow and we did grip now let's go ahead
and grip one more time
we'll pipe all of this into grip one
more time and this time i'm going to do
a
inverse script so i'm going to do dash v
meaning return
all the lines except the ones that have
this string
so i'm going to do inside single quotes
again i'm going to do dash dash
space and then comma space opening
parenthesis
single quotes so these lines here that
started with that string
i want to get rid of those so return all
the lines
that don't have this pattern that's what
the dash v flag
does for us and now that did not quite
work and i actually got an error message
because
grep does not like the dash dash pattern
we need to escape that so i need to do a
backslash dash backslash dash that
actually
grip we'll understand that as being dash
dash in the document
now when i run that we get exactly what
we wanted it looks like i still have one
more
commented line that didn't get filtered
out it's because i didn't keep the same
pattern instead of dash dash
space comma space that particular line
is dash dash
comma without a space i could actually
just fix that in the config since that's
really my fault for not keeping the same
pattern for all of my commented lines
i'm just going to fix that
right here in the config and now
when i run the grip command again
now that commented line is actually no
longer returned
so i'm just going to scroll through here
yeah it doesn't look like we have
any commented lines now so already this
is a
pretty clean layout it gives me the key
binding and the command it runs
and then at the end of the line i did
have some comments for
those of you that are using my config to
more specifically explain
exactly what the commands are in case
you don't understand you know what the
actual
commands in xmo ned do for example if
you didn't know
that the spawn xmonet restart command
restarts xmonet i went ahead and
commented it out specifically
you know so explicitly for you guys now
one thing that is a problem i noticed
is the very first key binding that is
returned here
is actually the second key binding in my
xml ad config let me
make the xml ad config full screen you
see because
that's the one key binding that doesn't
start with comma space
of opening parentheses it actually
starts with opening bracket space
opening parenthesis so i need to take
that into account here so
what i'm going to do i'm going to up
arrow and let's go ahead and add a rule
for that what i'm going to do is i'm
going to go back here to this first grip
here
i'm going to add the dash e flag because
we're going to do multiple grips here so
i'm going to do dash e again and then
inside single quotes i want to grip
for the opening bracket i have to escape
that so do a backslash bracket
space parentheses and then i think that
should work
now if i run that and let's scroll back
up and see if we actually get yeah now
we actually get the
very first key binding as well so now
we're actually seeing
every single key binding now i've still
got some work to do on cleaning this up
but this
a single line at the command line is
going to start getting very long so what
i'm going to do is i'm actually
just going to do a copy because let's go
ahead and put this in a real script
so i'm going to go ahead and create a
new file here
inside doom emac so i'm going to do a
space period because inside my
dot exmonad directory which we're
currently in because we're looking at
xmoned.h i'm going to go ahead and
create a shell script i'm going to name
it
xmonad underscore keys dot
sh and then it creates this new bash
script here because by default i've
got my emacs set up to where anytime i
create a shell script it gives me the
user bin
env bash shebang so it's going to be a
bash script
let me zoom in and what i'm going to do
is i'm just going to paste
what we had had in the terminal before
and let's go ahead and clean this up so
it looks a little better
so let's do some line breaks so in shell
scripting or
even at the command line running this
you could actually create some line
breaks with the backslash character so
that's what i'm going to do is i'm just
going to go ahead
and put a few backslashes just to
make this a little more readable and
i'm gonna go ahead and do colon w to
write that and i'm gonna open up a
new terminal here and i'm gonna cd into
dot xmonet that directory if i did a ls
you see
xml add underscore keys so what we need
to do is run the command
ch mod uh plus x because we want to make
this script executable because it will
not run
if it's not executable and now that i've
done that you know we could actually run
this if we wanted to
and you see how that works let me go
ahead and zoom in on this terminal
because this will be the terminal we use
from here on out let me go back
uh to the other terminal here i'll just
close that out
now we'll just play around in this shell
script instead of doing this at the
command line it'll be easier to read
this way
now one thing i didn't like about the
output from this command
is the fact that every line has a whole
bunch of leading spaces
so i want to get rid of that so and the
reason it has leading spaces is because
the lines
it's actually pulling out of my config
have leading spaces because they have to
you know i can't have
these lines starting at the beginning of
the line because haskell is really picky
about spacing so i actually need the
spaces in the config file
but i want to get rid of the spaces when
i actually have this printed out in the
terminal
and we can do this with a regular
expression here what i want to do
i probably want to do this with said let
me get back into insert mode
and i'm going to pipe all of this into
sid this time
and we'll do said dash e because we may
do multiple set statements
and then we're going to do single quotes
s because we're going to do a
substitution what do i want to
substitute
i want to substitute the carrot symbol
which signifies the beginning of the
line
and then inside brackets i want to do a
space or
tab and then the asterisk symbol what
this signifies is find the beginning of
the line if
everything at the beginning of the line
is tabs or spaces i want you to replace
it with what
with nothing and i think that's really
all i want to do there so let me go
ahead and write
and then get back to the terminal and
let's go ahead and rerun our script
and see if that actually works it did it
removed all of those leading spaces
to clean it up a little further i think
i would want to get rid of the leading
comma space on each line as well so
let's get back to the script here let me
get into insert mode and i'm just going
to do another
dash e we're going to continue with said
substitutions here
and then we're going to do a
substitution for the comma space
parentheses and then what we want to
substitute that for
is just parentheses and then do the
trailing slash
at the end and if i do colon w and then
get back to the terminal
and run that that did not work because i
obviously
made a mistake here because i didn't add
the
backslash to signify a line break there
so let me
put that in its place and then go back
to the terminal and rerun that
and now we get rid of the opening comma
space
that was at the beginning of each line
of course remember there is the one line
that's not going to look right because
the very beginning line had a bracket
and of course we could take that into
account as well if i get back into the
script
once again let's go ahead and create a
new line here we'll do
dash e because we'll continue on with
sid this time what are we going to
substitute
we are going to substitute an opening
bracket
space opening parenthesis and we want to
substitute that
with just opening parenthesis and then
do the trailing slash
emax annoyingly anytime you do anything
with brackets parentheses it likes to
add the closing one
which is great sometimes but in this
particular case it's actually getting
in my way i can actually turn that off
but i won't bother
and now when i run the script let's see
if it fixes the very first
line and now the very first line looks
the same as the rest of the lines
now one thing i don't like about this
gigantic list of key bindings
is it's all one big block of text
there's no real
breaks one thing i would find
interesting
is if i could actually group the key
bindings which i i've grouped them
in my config file right i've grouped
them by category for example
all of the d menu key bindings are in
one section and all of the emacs key
bindings are in one section etc
and i i want to keep that and i would
like those comments
for the types of keybindings to actually
be outputted as well
but remember we stripped out all the
comments everything that began with dash
dash
but i think we could fix this if we just
add a specific string that we can
you know do something with grip or sid
with later so once again i'll do
all caps and i'll just create a tag
essentially i'll do kb for key binding
underscore group so these will be key
binding groups here
and then the name of the group in this
case these are x monet key bindings
and i could go down here and do the same
thing so once again i'll
add kb underscore group what i probably
should do is just get
into visual mode here and actually yank
that and just copy it that way i can go
down here
and just paste it a million times so
that i've got
each category here i'm going to write
that i'm not going to go through and do
it to every single
group here i'll just do four of them
just to see if this actually works
and then what i want to do is get back
into our script what i want to do
is i want to go back to where we were
gripping with the dash e flag i want to
create a new line let's do dash e one
more time
this time i want to grip this particular
string kb
underscore group let's write that let's
go to the terminal
run the script and now let's go back to
the top of the document and see
if that worked for us and it did not so
obviously
we made a mistake there ah obviously i
needed to add a pipe
and then of course let's make sure we
get the line break there with the
backslash
let me write that again so that was just
a dumb mistake on my part let's rerun
the script
and now we get an error that dash e
command
is not found so now we had the pipe
on this line that doesn't need to be
there so we only need to pipe
when we're actually piping into grip or
sid we don't need a pipe symbol
when we're just continuing on with dash
e
so now let's run the script the script
actually works this time let's see if we
actually have the
group headings the lines with the group
names no we do not
so we keep making mistakes but that's
fine i leave all the mistakes in the
videos because
that's part of learning is seeing
somebody screw up and you guys hopefully
don't do this when you're doing your
scripting but honestly when you're doing
one of these
scripts on the fly there's a lot of
trial and error with them
and looking at this i really think this
should have worked i'm not seeing the
error the
others you know when they didn't work i
obvious i immediately spotted the error
but this looks like it should work so
what i'm thinking
yeah i know what it is i'm an idiot i
changed my config file
i didn't write it and then i need to run
a org bevel tangle to have that output
to xmonet.hs
and i'm betting now the script actually
works if i go back here and run the
script and
let me scroll back up and now yeah we
actually get the group name
exmonad run prompt other d menu prompts
of course we also get dash dash
kb group so now what we need to do is
get into the script
and what we need to do is get rid of
dash dash space
kb group on those lines i think how i
want to play that
is i'm just going to go ahead and do
this with sid so i'm gonna add the
backslash four line break just continue
on dash
e here and then inside single quotes
we'll do a substitution again
what am i substituting i'm gonna
substitute dash dash space
kb underscore group space because
i want to get rid of the space after kb
underscore group as well and then
slash and then what do i want to replace
this with i actually want to replace it
could i replace it with a new line slash
let's see that if that works i'm going
to write that
let's go ahead and get back to the
terminal and run that and see how that
looks
scroll back up and that looks really
really nice right because i
added a line break before
the group name now one thing i don't
like is i don't like that i
have the comma separating the key
binding from the command it runs i'd
rather that
not be a comma i wanted something more
something that stands out a little bit
more visually i think i'd rather change
that
maybe to a colon so let me get back into
the script and what i'm going to do is
i'm just going to
go ahead and add another said
substitution so
let's go ahead and substitute a double
quote comma space
because that was the pattern and i would
rather that be a double
quote space colon space and then i'm
going to do the
trailing slash and then the trailing
single quote
and let's see if that actually works for
us so let me rerun the script
and yeah i think that is a little bit
more
easier to read i think that visually
that stands out a little more than
having that comma right behind the
double quotes now we have space colon
space
and if i wanted this to line up even
better what i could do is i can actually
change the space i could do something
like uh
change the space to a tab and let's see
how that looks rerun the script and yeah
and now
that's even better as far as visually
separating the keybinding
from the commands now the next thing i
want to do is i don't want this
information to have to always be
output in a terminal i would rather this
output in a graphical window a dialog
box and on linux the most common dialog
box program is a program called yad
which stands for
yet another dialog and what i'm going to
do is we're just going to
pipe all of this information and let me
go ahead and add the pipe symbol and
i'll go ahead and create a line break as
well i'm going to pipe this
into yad dash dash text dash
info and that is the type of box we're
creating with the yeah
dialog box program is it's a text info
box because
there's a whole bunch of windows you can
create with yeah you can create
message windows and and things like that
so i'm going to go ahead and do a colon
w to write that
and then go back to the terminal and now
run the script and it opens this
yeah dialog box it opens it full screen
because we were in full screen mode but
if i was in tiling mode
it would just be a standard tiling
window now i don't want
that to actually be tiling i don't want
it to be full screen either what i would
like
is i would like to have that open at a
specific size and centered on the screen
so what i'm going to do is i'm going to
get back into insert mode here
and another thing i want to do is i want
to change the colors because i didn't
like the
gtk color scheme of those windows i'd
rather it
respect kind of like my emacs color
scheme or my terminal color scheme
and in this program yeah you can
actually specify a background color and
a foreground color so i could do dash
dash
back equals and then give it a
background color i'm going to do
2 8 2 c 3 4. that's the background color
that i use in emacs and in my terminal
color schemes and then
i'm going to do dash dash 4 equals for a
foreground color
and for that i'm going to do 4 6 d 9
and then what i want to do is do dash
dash geometry
equals and i want this to be 1200 pixels
by 800 pixels in size
and then let me do colon w to write that
and then let me go ahead
and run that and see how that looks it's
still full screen
if i was in tiling mode it would still
be tiling the problem here
is you know setting the geometry works
fine if we were in a floating window
manager but a tiling window manager
always
forces things to tile so this is not a
problem with the script necessarily it's
a problem with my ex monad config i need
to set a window rule
that all yet windows are floating so
what i need to do is get into my exmonet
config
and then i'm going to page up to where i
have some window rules
settings and you see things like class
name equals and then the name
of the the windows and then do float
these are all the windows that i want to
always be floating such as for
example class name
equals do float so i'm just going
to go in here and i'm going to
yy to copy and p to paste and then i'm
going to create class name
equals and i'm going to do yet i'm
assuming that the window name is
actually yad
and then i'm going to do do float but
really what i want to do is
do center float because xmonet has the
ability
to force a floated window to also be in
the center of the screen now if i do
colon w to write that and then let me
write that to xmonet.hs and i'm going to
restart
xmonad and i get an error message
and the good thing about xmonet is it's
really good about error messages as far
as it tells you exactly what the problem
is
the problem is do center float i didn't
import
a library that has a do center float
module it actually tells me that right
here it tells me i should have imported
xmonet.hooks.managehelp
do center float so let me get back into
my config
i'm going to go to the top of the
document here because that's where my
imports are
and i need to import xml ad hooks
manage helpers which i've already got
but i specified only two modules is full
screen and do full float i need to go
ahead and add do
center float let me go ahead and write
that
next monad restarted without any errors
so
now when i run the script it should
open in the center of the screen so let
me just run that from the terminal here
and i'm in tiling mode and let's see if
it actually yes it forces the window
centered in the middle of the screen
with 1200 by 800 pixels for the size
and it respected my background color and
the foreground color i
chose so that is how i would do that the
last thing i probably would do for
purposes of this video i don't want to
run this
from a command line i don't want to run
this from a run launcher you know i want
a key binding to where
i hit a key binding and this window with
all of my key bindings pops up so what i
need to do is i need to put that of
course
in my ex monad config so let me go down
to where all of my key bindings are
and i'm just going to add a new one let
me find the very beginning of my key
binding list
because it needs to go in the keybinding
group for the exmonadd keybindings so
i'm just going to go ahead and create a
new one so i'm going to do comma
and then inside parentheses here inside
double quotes i'm going to do
mod shift slash now mod shift slash is
really
mod question mark because the question
mark is typically the key
you hit in many programs to get help so
it makes sense for this keybinding to
actually be mod shift
slash or mod question mark and i need to
do a comma behind that
and then the command we're going to run
the command we're going to run of course
needs to be
spawn and then what are we spawning we
are going to spawn the path
to that script which is in my home
directory slash
dot x monad slash x monad underscore
keys dot sh and let me escape and let me
write that
and now let me restart xmo ned
and now let me do mod question mark and
now mod question mark brings up the
window with our key bindings how cool is
that
that's very nice and of course i could
clean this script up a lot more and make
the
you know this look a little bit better
because honestly i could format that a
lot better
but really this works i mean if you had
a
problem figuring out what your exmo ned
key bindings this works i mean i i can
easily read this to figure out what key
binding does what
and of course just because i did this in
exmo ned i mean you could
write a script to grip and set out all
that information for
q-tile or i3 or bspwm or whatever window
manager you use
now obviously that was a very quick and
dirty script i didn't spend what 10
15 minutes and we just kind of going at
we're winging it right
and i did everything with sid and grip
which i purposely was trying to do
said and grip i was trying to actually
avoid using awk because i used typically
use awk
a lot in my scripts and people complain
man you using awk why didn't you use sid
for that why didn't you use grip for
that well
here you go and honestly i'm not even
sure she'll scripting
is the best way to accomplish this
ideally what you would want to do is if
you actually knew haskell
because ex-monad's written in haskell
the config files written in haskell
it would be great if i knew enough
haskell where i could actually get this
information
by adding some haskell code to my config
but
i am nowhere near a haskell master it's
a lot easier
just to quickly throw together this
quick shell script now before i go
i need to thank a few special people i
need to thank the producers of this
episode absolutely gabe james mitchell
paul west sakami allen chuck gert david
dilling gregory hi co-ariana alexander
peace archan fedor polytech raver red
prophet scott
stephen and willie these guys they're my
highest tiered patrons over on patreon
without these guys
this episode that you just watched would
not have been possible the show is also
brought to you by each and every one of
these ladies and gentlemen as well all
these names you're seeing on the screen
each and every one of these ladies and
gentlemen help support me over on
patreon because i don't have any
corporate
sponsors i'm sponsored by you guys the
community
if you like my work you want to help me
out please consider subscribing to
distrotube over on patreon
alright guys peace
and yes i'll push the script to my
gitlab
