Quick access to local off-line reference docs through key-binding
Tags: ubuntu, productivity, webdev, bash
Published: 2019-12-02 12:48:56

Through a simple key-binding (*shift+ctrl+d*) I can quickly launch or focus reference documentation (using [devdocs](https://devdocs.io/)).

![Quick open reference docs after pressing a key-binding](https://imgur.com/ZSW4eVJ.gif)

So, how are we going to do this?

1. We're going to install some software to facilitate the mechanics: `wmctrl`, `nativefier` and `devdocs`
2. We're going to write a bash script that launches or focuses the devdocs
3. We're going to bind the bash script to a key-binding

*(nb: This guide was tested on Ubuntu 18.04)*

## 🛃 Installing `wmctrl` (1 of 3)

What's `wmctrl` and why do we need it?

```
$ man wmctrl

NAME
       wmctrl - interact with a EWMH/NetWM compatible X Window Manager.

...

DESCRIPTION
       wmctrl  is  a  command that can be used to interact with an X Window manager that is compatible with the EWMH/NetWM specification.  wmctrl can query the window manager for information, and it can request that certain window
       management actions be taken.
```

We'll use `wmctrl` to check if our API reference application is running,  and focus on it. If it's not running, we'll start it. `wmctrl` is easily installed on Ubuntu through the package manager:

```
# Installs wmctrl
sudo apt install wmctrl
```

## 💡 Installing `nativefier` (2 of 3)

[Nativefier](https://www.npmjs.com/package/nativefier) is a tool to make a native wrapper for any web page. We'll use it to get a local version of DevDocs installed, in case we're ever without Wi-fi.

It's quite easy to install, just run the following `npm` command to install it as a global dependency:

```
# Install nativefier globally
npm install nativefier -g
```

## 📖 Installing `devdocs` (3 of 3)

This is the actual documentation tool we'll be using. You can insert your own if you like. 

We'll use `nativefier` to install a local version of DevDocs:
```
# Create software folder
mkdir ~/Software && cd ~/Software

# Generate local electron version of devdocs
nativefier --name "DevDocs" "https://devdocs.io/"
```

We also want to have a `.desktop` file installed, so we can launch the application and save it in our favorites sidebar:

```
echo "[Desktop Entry]" \
   "Type=Application" \
   "Terminal=false" \
   "Exec=/home/<your-username>/Software/dev-docs-linux-x64/dev-docs" \
   "Name=DevDocs" > \
   "# Icon=/path-to-optional-icon.png" \
   > ~/.local/share/applications/devdocs.desktop
```

*(If you're having an issue with adding the application to your favorites in a later stage, add the following to this file: `StartupWMClass=dev-docs-nativefier-49fe5b`. Where `dev-docs-nativefier-49fe5b` is the name you see when you hover over the running app icon in your application bar).* 


## 🚀 Implementing the launch script

```
# Create a folder to store our script
mkdir ~/bin

# Create launch/focus script
echo "#!/bin/bash" \
   (wmctrl -l | grep -q DevDocs) && wmctrl -a DevDocs || gtk-launch devdocs" \
   > `~/bin/devdocs.sh`

# Make the script executable for the user
chmod u+x ~/bin/devdocs.sh
```

What exactly does this script do? Let's break it down:
* `(wmctrl -l | grep -q DevDocs)`: List all applications and find `DevDocs`
* `wmctrl -a DevDocs`: If found, focus on application `DevDocs`
* `gtk-launch devdocs` if *not* found, launch application `devdocs`

### ⌨️ Adding key-binding

Adding the key-binding is easy in Ubuntu, go to `Settings` -> `Keyboard` and hit the `+` icon to add a new key-binding:

![Quickly configure key-binding](https://i.imgur.com/Kwqsdb8.png)

### 🎇 That's it!

Test your key-binding by hitting `shift+ctrl+d` (or your chosen binding). The devdocs application should launch, and if it's already running it should focus when using the key-binding.

If you want to run all of the above commands in one go, use the following gist:

```
bash <(curl -s https://gist.githubusercontent.com/flipflopsandrice/07d84567f4197ef253055066669078b3/raw/6976125db4d5b7b22ba69e5ed3206be223f1ea68/install-devdocs.sh)
```

{% gist https://gist.github.com/flipflopsandrice/07d84567f4197ef253055066669078b3 %}