Open File Explorer and Browser from ZSH
Tags: productivity, zsh, tutorial, terminal
Published: 2021-03-09 17:15:21

Have you noticed that we can open a folder inside VSCode with `code .` command?

Will it be cool if we could do the same to open the file manager on the current folder or open the browser on a specific path from the terminal (or from VSCode)? 

Well, it can be done by creating some functions and aliases 😎.

---

# Prerequisites

We need to install the [clipboard-cli](https://github.com/sindresorhus/clipboard-cli) package in order to use the `clipboard` no matter the OS we are using.

# Project

First of all, we need to create a folder to save our helper functions. I used to name it `.helpers` inside the home directory.

`take` command on zsh automatically creates folders and changes to the directory.

```
take .helpers/open
```

## Open

Now we are going to make a script to open folder/paths in File Explorer. Create a file called `open_path` inside the `open` folder and put this code.

```bash
#!/bin/bash

while getopts ":p:" opt; do
    case $opt in
        p) path="${OPTARG}"
        ;;
        \?) echo "Invalid option -${OPTARG}" >&2
        exit 1
        ;;
    esac
done

case $path in
    build)
        path="./build"
    ;;
    coverage)
        path="./coverage"
    ;;
esac

isWSL=$(uname -a | grep WSL)
if [[ -n "${isWSL}" ]]; then
    path=$(wslpath -w ${path})
fi

${OPEN} "${path}"
```

## Browser

Now we are going to make a script to open URLs or files in Browser. Create a file called `open_browser` inside the `open` folder and put this code.

```bash
#!/bin/bash

while getopts ":f:u:p:" opt; do
    case $opt in
        f) file="${OPTARG}"
        ;;
        u) url="${OPTARG}"
        ;;
        p) port="${OPTARG}"
        ;;
        \?) echo "Invalid option -${OPTARG}" >&2
        exit 1
        ;;
    esac
done

address=""
if [ -n "${file}" ]; then
    case $file in
        coverage)
            launcher=${BROWSER}
            file="./coverage/lcov-report/index.html"
        ;;
    esac

    isWSL=$(uname -a | grep WSL)
    if [[ -n "${isWSL}" ]]; then
        file=$(wslpath -w ${file})
    fi
    address="${file}"
fi

if [ -n "${port}" ]; then
    pattern="^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$"
    if [[ ${port} =~ ${pattern} ]]; then
        url="${url}:${port}"
    fi
fi

if [ -n "${url}" ]; then
    pattern="^(http|https)://"
    if (! [[ "${url}" =~ ${pattern} ]]); then
        url="https://${url}"
    fi
    address="${url}"
fi

${BROWSER} "${address}"
```

### GitHub

Now we are going to make a script to get the git repo URL. Create a file called `get_repo_url` inside the `open` folder and put this code.

```bash
#!/bin/bash

url="$( git config remote.origin.url | sed -e "s/git@github.com:/https:\/\/github.com\//g" )"
if [ "${url:(-4)}" == ".git" ]; then
    url="$( echo "${url}" | rev | cut -f 2- -d '.' | rev )"
fi

echo "$url"
```

Now we are going to make a script to browse the GitHub repository. Create a file called `open_git_repo` inside the `open` folder and put this code.

```bash
#!/bin/bash

url="$( get_repo_url )"
${BROWSER} ${url}
```

Now we are going to make a script to browse the GitHub repository on current branch. Create a file called `open_git_branch` inside the `open` folder and put this code.

```bash
#!/bin/bash

url="$( get_repo_url )"
current="$( git branch --show-current )"
${BROWSER} "${url}/tree/${current}"
```

Now we are going to make a script to browse the GitHub repository pull requests section. Create a file called `open_git_pull` inside the `open` folder and put this code.

```bash
#!/bin/bash

url="$( get_repo_url )"
${BROWSER} "${url}/pulls"
```

Now we are going to make a script to browse the GitHub repository comparing current branch with another branch (`dev` as default). Create a file called `open_git_compare` inside the `open` folder and put this code.

```bash
#!/bin/bash

base="dev" #default base branch
if [[ ! -z $1 ]]; then
base="$1"
fi

url="$( get_repo_url )"
current="$( git branch --show-current )"
if [ "$current" != "${base}" ]; then
    url="${url}/compare/${base}...${current}"
else
    url="${url}/compare/${base}..."
fi
${BROWSER} ${url}
```

## npm

Now we are going to make a script to browse the npm package project. Create a file called `open_npm_package` inside the `open` folder and put this code.

```bash
#!/bin/bash

package="$(node -p "require('./package.json').name")"
if [[ -z "$package" ]]; then
    echo "No package.json found"
    exit 1
fi

${BROWSER} "https://www.npmjs.com/package/${package}"
```

Now we are going to make a script to browse the an npm package searching by the name on `clipboard`. Create a file called `open_npm_clipboard` inside the `open` folder and put this code.

```bash
#!/bin/bash

# Requires:
# https://github.com/sindresorhus/clipboard-cli
# npm install -g clipboard-cli

url="https://www.npmjs.com/package"
value="$( clipboard )"
if [[ -n $value ]]; then
    url="$url/$value"
fi

${BROWSER} ${url}
```

---

# Permissions

Add execution permissions to those files with:

```bash
chmod +x ~/.helpers/**/*
```

---

# Path and Alias

It's not good idea navigate to `.helpers/open` folder each time we want to use those commands. 

In order to make it globally available need to add this `PATH` and aliases to `.zshrc`.

```bash
export OPEN="explorer.exe" #wsl2
export BROWSER="${OPEN}" #wsl2
export PATH="$HOME/.helpers/open/:$PATH"
# Open
alias o="open_path -p ." # open current folder
alias op="open_path -p" # +path
alias opb="open_path -p build" # open build path
alias opc="open_path -p coverage" # open coverage path
# Browse
alias b="open_browser -f ./index.html" # browse index.html
alias bu="open_browser -u" # +url
alias blh="open_browser -u http://localhost"
alias blhp="open_browser -u http://localhost -p" # +port
alias bcr="open_browser -f coverage" # browse coverage
alias bgr="open_git_repo" # browse git repo
alias bgb="open_git_branch" # browse git repo on current branch
alias bgp="open_git_pull" # browse git repo pulls
alias bgc="open_git_compare" # +base branch
alias bnp="open_npm_package" #browse npm package
alias bnc="open_npm_clipboard" #browse npm package from clipboard
```

> `OPEN` and `BROWSE` constants need to be configured according yor OS. Windows (WSL2) and macOS use the same command to open the file explorer or the default web browser, on Ubuntu (Linux) need to be specified each one.

|SO|`OPEN`|`BROWSER`|
|---|---|---|
|Windows (WSL2)|`"explorer.exe"`|`"${OPEN}"`|
|macOS|`"open"`|`"${OPEN}"`|
|Ubuntu|`"xdg-open"`, `"gnome-open"`, `"nautilus"` ...|`"googlechrome"`, `"firefox"` ...|

Once finish, reopen all terminals or update his source running source ~/.zshrc command and now you can use the new commands.

---

# Usage

Navigate to the path where you want to use the commands or aliases.

## File Explorer

|Alias|Command|Description|
|---|---|---|
|`o`|`open_p -p .`|Open current path on file explorer or finder|
|`o <path>`|`open_p -p <path>`|Open a relative or absolute path on file explorer or finder|

## Browser

|Alias|Command|Description|
|---|---|---|
|`b`|`open_browser -f ./index.htm`|Open a browser with `index.html` on current path|
|`bu <url>`|`open_browser -u <url>`|Open a browser with specified URL|

## React/Web

|Alias|Command|Description|
|---|---|---|
|`obf`|`open_path -p build`|Open `.\build` folder inside current path on file explorer or finder|
|`obc`|`open_path -p coverage`|Open `.\coverage` folder inside current path on file explorer or finder|
|`bcr`|`open_browser -f coverage`|Open coverage `.\coverage\lcov-report\index.html` report on Browser|
|`blh`|`open_browser -u http://localhost`|Open a browser as `localhost`|
|`blhp <port>`|`open_browser -u http://localhost -p <port>`|Open a browser as `localhost` on specific `port`|

## GitHub

|Alias|Command|Description|
|---|---|---|
|`bgr`|`open_git_repo`|Browse the current GitHub repo url|
|`bgb`|`open_git_branch`|Browse the current GitHub current Branch url|
|`bgp`|`open_git_pull`|Browse the current GitHub Pull Request url|
|`bgc [<branch>]`|`open_git_compare [<branch>]`|Browse the compare current branch with another base branch [`dev` by default] |

> Works with repositories cloned with HTTP or SSH

## NPM

|Alias|Command|Description|
|---|---|---|
|`bnp`|`open_npm_package`| Browse the NPM package on `package.json`|
|`bnc`|`open_npm_clipboard`|Browse the NPM package on browser searching by name on clipboard|

---

You can download or clone this code and other ZSH utilities from GitHub: [dot Files](https://github.com/deinsoftware/dot-files) repository.

---

**That’s All Folks!**
**Happy Coding** 🖖

[![beer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkgsx4aw6qn9i9ax6as9.png)](https://github.com/sponsors/deinsoftware)