<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>sglavoie.com – Tag: dmenu</title><link>https://www.sglavoie.com/tags/dmenu/</link><description>Posts and writings by Sébastien Lavoie. Customization setups and articles on productivity for developers who like minimalism.</description><language>en</language><atom:link href="https://www.sglavoie.com/tags/dmenu/feed.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Sun, 10 Nov 2019 09:02:00 -0600</lastBuildDate><item><title>Using dmenu to Optimize Common Tasks</title><link>https://www.sglavoie.com/posts/using-dmenu-to-optimize-common-tasks/</link><description>If remembering dozens of keyboard shortcuts isn’t your forte, let dmenu come to the rescue! With this awesome tool, you will be able to create menus from plain text files swiftly and effortlessly (almost).</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://tools.suckless.org/dmenu"&gt;dmenu&lt;/a&gt; is one of those tools that look a little unimpressive at first but can accomplish so much! It&amp;rsquo;s a program that you can use to receive any output redirected from other programs (through pipes in the terminal, the symbol &lt;code&gt;|&lt;/code&gt;) and treat that output so that it can pop up within a simple menu to make it available for execution. If you want to know more about other fantastic tools from &lt;a href="https://suckless.org"&gt;suckless.org&lt;/a&gt;, I &lt;a href="https://www.sglavoie.com/posts/using-dmenu-to-optimize-common-tasks/"&gt;went over some of them before&lt;/a&gt;, such as the &lt;code&gt;st&lt;/code&gt; terminal and &lt;code&gt;slock&lt;/code&gt;, a dead simple screen locker.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="any-simple-example"&gt;Any Simple Example?&lt;/h2&gt;
&lt;p&gt;You bet! Before diving in with how to install it and some more concrete examples, you could give &lt;code&gt;dmenu&lt;/code&gt; a go with a simple command such as the following (assuming the program is installed on your machine).&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls &lt;span class="p"&gt;|&lt;/span&gt; dmenu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will effectively &amp;ldquo;pipe&amp;rdquo; the output of &lt;code&gt;ls&lt;/code&gt; into &lt;code&gt;dmenu&lt;/code&gt; and a menu like the following would appear (by default, it shows as a thin stripe at the top covering the width of the screen):&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command.png" alt="dmenu_ls_command" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you start typing, the displayed list will be filtered down like so:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command_typing.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command_typing.png" alt="dmenu_ls_command_typing" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also switch to the next item to be highlighted by typing &lt;code&gt;Ctrl + n&lt;/code&gt;, to the previous item by typing &lt;code&gt;Ctrl + p&lt;/code&gt; and exit by reaching for the &lt;code&gt;Escape&lt;/code&gt; key. For now, if you type &lt;code&gt;Enter&lt;/code&gt; once your desired selection is highlighted, the selection will be outputted to the terminal and that will be the end of it. Let&amp;rsquo;s convert this into a practical thing, then.&lt;/p&gt;
&lt;p&gt;Keeping the same output as before which only contained directories, we could open a file manager (here, I&amp;rsquo;m going with &lt;code&gt;pcmanfm&lt;/code&gt;) and do something like this (bear with me, the explanation follows!):&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls &lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -I &lt;span class="o"&gt;{}&lt;/span&gt; pcmanfm &lt;span class="s2"&gt;&amp;#34;{}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is now a fully functional example, albeit its practicality is debatable. What will happen, exactly?&lt;/p&gt;
&lt;p&gt;First, &lt;code&gt;ls&lt;/code&gt; will output a list of directories in the current working directory. That is, the following would be printed in the terminal without any piping:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Desktop Downloads Learning Pictures Public Templates virtualbox_vms
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Documents Dropbox Music Programming SortOut Videos&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When we &lt;em&gt;pipe&lt;/em&gt; this into &lt;code&gt;dmenu&lt;/code&gt;, we will get a menu with all that output nicely formatted vertically, which is what the &lt;code&gt;-l 5&lt;/code&gt; options does (here, we want only &lt;strong&gt;5&lt;/strong&gt; lines to show). We will see a maximum of &lt;strong&gt;5&lt;/strong&gt; items as this is the value we passed to the &lt;code&gt;-l&lt;/code&gt; option:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command_vertical_5_items.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_ls_command_vertical_5_items.png" alt="dmenu_ls_command_vertical_5_items" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can still start typing a word that doesn&amp;rsquo;t show up in this list like &lt;code&gt;Mu&lt;/code&gt; and we will see that this list is filtered to only include the matching directory &lt;code&gt;Music&lt;/code&gt; even though we couldn&amp;rsquo;t see it before since we limited our results to &lt;strong&gt;5&lt;/strong&gt; items. We could also use the same technique with &lt;code&gt;Ctrl + n&lt;/code&gt; and &lt;code&gt;Ctrl + p&lt;/code&gt; to cycle between the elements.&lt;/p&gt;
&lt;p&gt;Up to this point, we are getting our selection outputted to the terminal. Next, we pipe it into &lt;code&gt;xargs&lt;/code&gt;, which will allow us to specify a command to which we will pass our result (what is printed to the terminal) as an argument (we could make use of more arguments depending on the output we get, but let&amp;rsquo;s start simple). The &lt;code&gt;-I {}&lt;/code&gt; option will make it possible to &amp;ldquo;quote&amp;rdquo; our result so it is read as a single argument and properly &lt;em&gt;escaped&lt;/em&gt;. This means that without this option, if we have spaces or other special characters in the argument (such as a folder called &lt;code&gt;My Music&lt;/code&gt;), it would try to pass each word as a new argument to &lt;code&gt;pcmanfm&lt;/code&gt;, trying to open both &lt;code&gt;My&lt;/code&gt; and &lt;code&gt;Music&lt;/code&gt; directories at once.&lt;/p&gt;
&lt;p&gt;We are representing our output as &lt;code&gt;{}&lt;/code&gt; and when we quote it with &lt;code&gt;pcmanfm &amp;quot;{}&amp;quot;&lt;/code&gt;, spaces are interpreted without any trouble. If we wanted to use various arguments instead, we could try something like this:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;file1.txt file2.txt\nfile3.txt file4.txt&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs cat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The part before the first pipe character will print to the terminal those two lines:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;file1.txt file2.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;file3.txt file4.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When we pipe this into &lt;code&gt;dmenu -l 2&lt;/code&gt;, we will get this menu:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_echo_command_filenames.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_echo_command_filenames.png" alt="dmenu_echo_command_filenames" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Typing &lt;code&gt;Enter&lt;/code&gt; on one of the highlighted items would then trigger &lt;code&gt;xargs&lt;/code&gt; to pass the content literally to &lt;code&gt;cat&lt;/code&gt; as arguments, which would then print to the terminal the content of both &lt;code&gt;file1.txt&lt;/code&gt; and &lt;code&gt;file2.txt&lt;/code&gt; (the first line containing two arguments for &lt;code&gt;cat&lt;/code&gt;) or the content of both &lt;code&gt;file3.txt&lt;/code&gt; and &lt;code&gt;file4.txt&lt;/code&gt; (the second line also containing two arguments for &lt;code&gt;cat&lt;/code&gt;) in succession.&lt;/p&gt;
&lt;p&gt;Now that we got our feet wet with what &lt;code&gt;dmenu&lt;/code&gt; does (&lt;em&gt;displays a menu&lt;/em&gt;), we might want to install it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-do-you-install-it"&gt;How do You Install It?&lt;/h2&gt;
&lt;p&gt;In Manjaro Linux, it comes with &lt;code&gt;i3&lt;/code&gt; if you use that flavor of the distribution and can be opened by pressing the modifier key (either &lt;code&gt;Super/Windows&lt;/code&gt; key or &lt;code&gt;Alt&lt;/code&gt; key) along with the letter &lt;code&gt;d&lt;/code&gt;, as in the shortcut &lt;code&gt;mod + d&lt;/code&gt;, or by typing &lt;code&gt;dmenu_run&lt;/code&gt; in a terminal, which will present a list of installed applications to launch. Otherwise:&lt;/p&gt;
&lt;h2 id="debian-based-such-as-ubuntu"&gt;Debian-based (such as Ubuntu)&lt;/h2&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install dmenu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="arch-based-such-as-manjaro"&gt;Arch-based (such as Manjaro)&lt;/h2&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pacman -Syu dmenu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can also install it from your distribution&amp;rsquo;s package manager if available or &lt;a href="https://tools.suckless.org/dmenu"&gt;from source&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="useful-real-world-examples"&gt;Useful Real-World Examples&lt;/h2&gt;
&lt;p&gt;Here are a couple of ways I like to use &lt;code&gt;dmenu&lt;/code&gt; to open a menu with a list of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cheat sheets;&lt;/li&gt;
&lt;li&gt;filesystem paths;&lt;/li&gt;
&lt;li&gt;most used documents;&lt;/li&gt;
&lt;li&gt;documents &amp;amp; books I read at the university;&lt;/li&gt;
&lt;li&gt;custom scripts I want to run in the background.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are a few screenshots of how it currently looks like in my daily usage so you get a better idea.&lt;/p&gt;
&lt;h2 id="cheat-sheets"&gt;Cheat sheets&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_cheat_sheets.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_cheat_sheets.png" alt="dmenu_cheat_sheets" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="university-shortcuts"&gt;University shortcuts&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_university_shortcuts.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_university_shortcuts.png" alt="dmenu_university_shortcuts" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="file-manager-shortcuts"&gt;File manager shortcuts&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_file_manager_shortcuts.png"&gt;&lt;img src="https://www.sglavoie.com/images/posts/0018_using-dmenu-to-optimize-common-tasks/dmenu_file_manager_shortcuts.png" alt="dmenu_file_manager_shortcuts" class="max-size-img-post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, how does that all work? As a starting point, all of those menus are launched through a specific keyboard shortcut that uses a mnemonic for each one (&lt;code&gt;mod&lt;/code&gt; being the &amp;ldquo;modifier&amp;rdquo; key on &lt;strong&gt;i3&lt;/strong&gt;, which is set to &lt;code&gt;Super/Windows&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mod + Alt + c&lt;/code&gt;: &lt;strong&gt;c&lt;/strong&gt;heat sheets;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mod + Alt + d&lt;/code&gt;: &lt;strong&gt;d&lt;/strong&gt;ocuments;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mod + Alt + f&lt;/code&gt;: &lt;strong&gt;f&lt;/strong&gt;ile manager;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mod + Alt + s&lt;/code&gt;: &lt;strong&gt;s&lt;/strong&gt;cripts;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mod + Alt + u&lt;/code&gt;: &lt;strong&gt;u&lt;/strong&gt;niversity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s take the cheat sheets example, which is a bit more interesting since it launches different applications.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="setting-up-a-custom-command"&gt;Setting Up a Custom Command&lt;/h2&gt;
&lt;h3 id="configuration-for-i3-bind-a-keyboard-shortcut"&gt;Configuration for i3 (bind a keyboard shortcut)&lt;/h3&gt;
&lt;p&gt;Here, I&amp;rsquo;m using &lt;a href="https://i3wm.org"&gt;i3&lt;/a&gt; to set a keyboard shortcut to run a specific command, but this will be a similar experience on other window managers and desktop environments.&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# i3config file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# The backslash at the end of the line allows us&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# to split the line to increase readability&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Cheatsheets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bindsym &lt;span class="nv"&gt;$mod&lt;/span&gt;+Mod1+c &lt;span class="nb"&gt;exec&lt;/span&gt; --no-startup-id &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You would usually be able to launch a custom command from your environment through a keyboard shortcut. If passing a direct command such as the above one isn&amp;rsquo;t an option, you can always store it in a Bash script and run that Bash script instead as the designated custom command. The script would then contain the following:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;## Cheatsheets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As far as &lt;strong&gt;i3&lt;/strong&gt; is concerned, that&amp;rsquo;s all you need to do. You would need to reload the configuration file (by default: &lt;em&gt;i3config&lt;/em&gt;) where the previous &lt;code&gt;bindsym&lt;/code&gt; command has been set up to apply the changes (default shortcut to reload: &lt;code&gt;mod + Shift + c&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id="configuration-for-cheatsheetsconf"&gt;Configuration for cheatsheets.conf&lt;/h3&gt;
&lt;p&gt;The content of this file is literally what will be shown when &lt;strong&gt;dmenu&lt;/strong&gt; opens it. An excerpt:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;#---------- Cheat Sheets -------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash st -e nvim path/to/bash.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git zathura path/to/github.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vimwiki firefox path/to/vimwiki.html&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here, we have set a maximum of &lt;strong&gt;30&lt;/strong&gt; lines to be displayed (&lt;code&gt;-l 30&lt;/code&gt;). What follows after an element has been selected with &lt;strong&gt;dmenu&lt;/strong&gt; allows us to parse the content of the line and retrieve only the command we are interested in with &lt;code&gt;sed&lt;/code&gt; before passing that filtered content around to &lt;code&gt;sh&lt;/code&gt; to execute it as a shell command. With more complex commands requiring multiples arguments to be received, we could add one more pipe between &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;sh&lt;/code&gt; like this (or with &lt;code&gt;xargs -I {}&lt;/code&gt; to avoid problems with spaces):&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -r &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If the line we want to run only includes a path to a file as in:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;myshortcut path/to/file.pdf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We could instead pipe it into an external command of choice if the same program applies to all items presented in the menu, say Firefox:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/file.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -I &lt;span class="o"&gt;{}&lt;/span&gt; firefox &lt;span class="s2"&gt;&amp;#34;{}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;What&amp;rsquo;s nice with the way pipes work in a Unix-like system is that we can chain harmless commands until the very end so they will simply be printed to the terminal. In this example, if we want to see how to filter our lines before running a command, we can do so as follow.&lt;/p&gt;
&lt;h4 id="pipe-1"&gt;Pipe 1&lt;/h4&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you remember from the menu we saw earlier, there&amp;rsquo;s a shortcut to open a cheat sheet for Git. Let&amp;rsquo;s say we selected that one with &lt;strong&gt;dmenu&lt;/strong&gt;. Because our command isn&amp;rsquo;t doing anything with the result, it will be outputted to the terminal like so (just like in the excerpt of &lt;code&gt;cheatsheets.conf&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git zathura path/to/github.pdf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;What &lt;code&gt;sed&lt;/code&gt; does here is to cut everything from the beginning of the line up to where the command starts (that&amp;rsquo;s where we find &lt;a href="https://pwmt.org/projects/zathura/"&gt;zathura&lt;/a&gt;, which is a powerful document viewer), because we need to isolate that part of the line so it looks like a shell command we could run on its own. Let&amp;rsquo;s add a new pipe to our command and see what &lt;code&gt;sed&lt;/code&gt; does with it*.&lt;/p&gt;
&lt;p&gt;* &lt;sub&gt;We could have used other tools to parse the string like &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;cut&lt;/code&gt;, etc.&lt;/sub&gt;&lt;/p&gt;
&lt;h4 id="pipe-2"&gt;Pipe 2&lt;/h4&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If we select the same item as before with &lt;strong&gt;dmenu&lt;/strong&gt; to illustrate more clearly what this new addition does, we will get this output:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;zathura path/to/github.pdf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If we were to type this in the terminal (assuming the file exists and &lt;strong&gt;zathura&lt;/strong&gt; is installed!), that would do the trick and it would open with the specified document viewer. &lt;strong&gt;Pipe 2&lt;/strong&gt; and subsequent pipes before we execute something is where the filtering magic happen. In short:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Everything &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;| dmenu&lt;/code&gt; is how our input will look like when we run &lt;code&gt;dmenu&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Everything &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;| dmenu [options here] |&lt;/code&gt; is what we need to do to our input so that it is converted into a working shell command;&lt;/li&gt;
&lt;li&gt;Finally, what comes &lt;strong&gt;after the last pipe&lt;/strong&gt; (either &lt;code&gt;xargs&lt;/code&gt;, &lt;code&gt;sh&lt;/code&gt; or a combination of both) is our way to redirect our string to the shell so it can be executed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once we are visually satisfied with how our command is supposed to look like (it has to be something that works when typed directly in the terminal), the next step is to pipe it again so it can be executed.&lt;/p&gt;
&lt;h4 id="pipe-3"&gt;Pipe 3&lt;/h4&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat path/to/cheatsheets.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;|&lt;/span&gt; dmenu -l &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/.* \+//&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There we go, the command is launched. If we keep the same simple syntax in all of our &lt;code&gt;.conf&lt;/code&gt; files —or whatever extension we choose— where the content of our menus is stored in plain text, we can quickly and painlessly create keyboard shortcuts to run custom lists of commands that can be edited on the fly. Once our shortcuts are active, it&amp;rsquo;s only a matter of editing one of those &lt;code&gt;.conf&lt;/code&gt; files and automatically our lists will be up-to-date when we trigger the shortcut again.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="running-a-custom-script"&gt;Running a Custom Script&lt;/h2&gt;
&lt;p&gt;If we want to run custom scripts, we need to indicate a command that would work in the terminal, such as &lt;code&gt;python myscrypt.py&lt;/code&gt; or &lt;code&gt;./myscript.sh&lt;/code&gt;. When it comes to shell scripts, we have to make sure they are executable. We can do so through a file manager or within the terminal like this:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x path/to/script.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will add the necessary permissions for the user to execute the script. As we already know, we would then need to add a keyboard shortcut to launch our custom menu and store our command in a file like &lt;code&gt;scripts.conf&lt;/code&gt; that would contain the following:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;#---------- scripts.conf -------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;myscript script.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And that&amp;rsquo;s all there is to know to get piping with &lt;code&gt;dmenu&lt;/code&gt;! You may also find &lt;a href="https://www.youtube.com/watch?v=8E8sUNHdzG8"&gt;this video from Luke Smith&lt;/a&gt; on YouTube to be quite helpful as well, which is where the inspiration for this post came from. He also &lt;a href="https://www.youtube.com/watch?v=R9m723tAurA"&gt;posted a complementary video&lt;/a&gt; about adding prompts to your commands which is a nice way to add interactivity to your scripts!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="chaining-dmenu-prompts"&gt;Chaining dmenu prompts&lt;/h2&gt;
&lt;p&gt;Another useful scenario is when you want to take a specific action based on the output of a previous command. For instance, let&amp;rsquo;s say you want to read a book but when you choose a &lt;code&gt;pdf&lt;/code&gt; with &lt;code&gt;dmenu&lt;/code&gt;, you want to be prompted for which reader to use while you want to let the system choose the default application for other types of files (e.g. &lt;code&gt;epub&lt;/code&gt; or &lt;code&gt;mobi&lt;/code&gt;). This could be achieved with a script similar to the following one:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;find ~/Documents/calibre_library -type f -iname &lt;span class="s2"&gt;&amp;#34;*.pdf&amp;#34;&lt;/span&gt; -o &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -iname &lt;span class="s2"&gt;&amp;#34;*.epub&amp;#34;&lt;/span&gt; -o -iname &lt;span class="s2"&gt;&amp;#34;*.mobi&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; dmenu -l 30&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; *.pdf &lt;span class="o"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;READER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;zathura\natril&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; dmenu -i -p &lt;span class="s2"&gt;&amp;#34;Which reader?&amp;#34;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$READER&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; xdg-open &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s what&amp;rsquo;s happening:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We &lt;code&gt;find&lt;/code&gt; all the files (&lt;code&gt;-type f&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;in the directory &lt;code&gt;~/Documents/calibre_library&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;that match a pattern that&amp;rsquo;s case-insensitive with &lt;code&gt;-iname&lt;/code&gt; (here, ending in either &lt;code&gt;pdf&lt;/code&gt;, &lt;code&gt;mobi&lt;/code&gt; or &lt;code&gt;epub&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;matching one file at a time (&lt;code&gt;-o&lt;/code&gt; can be interpreted to mean &amp;ldquo;only&amp;rdquo; and will keep searching if the previous file extension was not matched)&lt;/li&gt;
&lt;li&gt;then presenting 30 lines (&lt;code&gt;-l 30&lt;/code&gt;) of results at a time with &lt;code&gt;dmenu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;then, if the file is a PDF, prompts whether to use &lt;code&gt;atril&lt;/code&gt; or &lt;code&gt;zathura&lt;/code&gt; as the file reader and open with the chosen program&lt;/li&gt;
&lt;li&gt;otherwise, open the file with the default application.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="customize-the-look-of-dmenu"&gt;Customize the Look of dmenu&lt;/h2&gt;
&lt;p&gt;As they say, &lt;em&gt;&amp;ldquo;beauty is in the eye of the beholder&amp;rdquo;&lt;/em&gt;. If you would rather make some changes to how dmenu look, you can. &lt;strong&gt;dmenu&lt;/strong&gt; will be searching for the configuration file located at &lt;code&gt;~/.dmenurc&lt;/code&gt;, which could contain something as put below (with this configuration, it will look like the screenshots shown previously):&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ~/.dmenurc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# define the font for dmenu to be used&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_FN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;NotoSans-10.5&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# background colour for unselected menu-items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_NB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#161925&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# textcolour for unselected menu-items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_NF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#fdfffc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# background colour for selected menu-items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_SB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#235789&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# textcolour for selected menu-items&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_SF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#fdfffc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# command for the terminal application to be used:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TERMINAL_CMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;st -e&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# export our variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DMENU_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-fn &lt;/span&gt;&lt;span class="nv"&gt;$DMENU_FN&lt;/span&gt;&lt;span class="s2"&gt; -nb &lt;/span&gt;&lt;span class="nv"&gt;$DMENU_NB&lt;/span&gt;&lt;span class="s2"&gt; -nf &lt;/span&gt;&lt;span class="nv"&gt;$DMENU_NF&lt;/span&gt;&lt;span class="s2"&gt; -sf &lt;/span&gt;&lt;span class="nv"&gt;$DMENU_SF&lt;/span&gt;&lt;span class="s2"&gt; -sb &lt;/span&gt;&lt;span class="nv"&gt;$DMENU_SB&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Hopefully this introduction to what &lt;strong&gt;dmenu&lt;/strong&gt; has to offer gave you some ideas. I hope you&amp;rsquo;ll find many ways to adapt the examples so you can benefit from this amazing tool. You can find more configuration details in my &lt;a href="https://github.com/sglavoie/dotfiles/"&gt;dotfiles on GitHub&lt;/a&gt; for anything related to &lt;strong&gt;i3&lt;/strong&gt;, &lt;strong&gt;dmenu&lt;/strong&gt;, &lt;strong&gt;zathura&lt;/strong&gt;, &lt;strong&gt;st&lt;/strong&gt;, &lt;strong&gt;slock&lt;/strong&gt; and many more useful programs.&lt;/p&gt;
&lt;p&gt;Have a good time automating your digital life!&lt;/p&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sun, 10 Nov 2019 09:02:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/using-dmenu-to-optimize-common-tasks/</guid><category>tips-and-tricks</category><category>bash</category><category>dmenu</category><category>i3</category><category>linux</category><category>productivity</category><category>script</category></item></channel></rss>