qutebrowser Userscripts on Windows
Updated 2021-September-13

Page contents

News

2021-October-21  qutebrowser v2.4.0 released. To keep up with qutebrowser releases, see github.com/qutebrowser/qutebrowser/releases, lists.schokokeks.org/pipermail/qutebrowser/, or old.reddit.com/r/qutebrowser/.

2021-March-28  Published this evolving⁠[1] article.

 

Prerequisites

This article assumes…

 

About qutebrowser userscripts

A qutebrowser userscript can be run on a web page or on a fragment of a web page. To learn about userscripts, see…

 

Limitations of userscripts on Windows⚠️

On Windows, only userscripts with .bat, .cmd, .com, and .exe extensions will be launched by qutebrowser. This means that if you want to run a bash or python script from within Windows qutebrowser, you need to create a .bat, .cmd, .com, or .exe wrapper for it.

Examples of wrapper scripts are below.

 

About qutebrowser’s config and data directories

A fresh install of qutebrowser on Windows usually creates the following directory structure.

~\
└── AppData\
    └── Roaming\
        └── qutebrowser\
            ├── config\
            │   ├── greasemonkey\
            └── data\
                └── greasemonkey\

 

Note that…

  • On Windows, ~ is also known as %HOME% and %USERPROFILE%.⁠[2] It is usually located in C:\Users\USERNAME (with USERNAME replaced with your user name).

  • To find out the location of your qutebrowser config and data directories, run the :version command from within qutebrowser.

  • Windows default is to hide the ~\AppData\ directory. To unhide it, select Show hidden files, folders, and drives in File Explorer’s View Options.

 

About the greasemonkey subdirectories

Greasemonkey scripts are entirely different from qutebrowser userscripts, but I mention them here because a default installation of qutebrowser automatically creates empty greasemonkey\ directories in the config and data directories. To learn about greasemonkey scripts, which are written in JavaScript, see wikipedia.org/wiki/Greasemonkey.

💡
If you do not use these greasemonkey directories, it’s OK to delete them.

 

Five steps to create a simple Windows userscript

1. Create a userscripts subdirectory

Use either Windows File Explorer or the command line to create a userscripts\ subdirectory in either your qutebrowser config\ or data\ directory.

 

💡

If you are using qutebrowser v2.0.0+, I recommend creating config\userscripts\ because then your qutebrowser userscripts and configuration file(s) will all be located in the config directory.

If you are using qutebrowser v1.14.1 or earlier, you need to use data\userscripts\ (because config\userscripts\ was introduced in v2.0.0).

 

After the next couple steps, your directory structure will include this (assuming you are using qutebrowser v2.0.0+):

~\
└── AppData\
    └── Roaming\
        └── qutebrowser\
            ├── config\
            │   ├── greasemonkey\
            │   ├── userscripts\
            │   │   └── qb-env.cmd
            │   └── config.py
            └── data\
                └── greasemonkey\

 

2. Create qb-env.cmd batch file

Create a plain text file named qb-env.cmd in the userscripts\ directory that you created in the previous step that contains this:

@echo off

rem created: 2021-10-21
rem filename: qb-env.cmd

echo Hello from qb-env.cmd!

rem next line echoes a blank line
echo(
echo Working directory is...
cd

echo(
echo Active code page is...
chcp

echo(
echo Environment variables starting with QUTE are...
set QUTE

echo(
echo Environment variables starting with PATH are...
set PATH

rem If Git Bash's sh.exe is on your path, uncomment next 7 lines
rem echo(
rem echo Git Bash: pwd
rem "sh.exe" -l -c "pwd"

rem echo(
rem echo Git Bash: printenv | grep -i qute
rem "sh.exe" -l -c "printenv | grep -i qute"

 

qb-env means qutebrowser environment and the above batch file displays the working directory, active code page, and some environment variables.

If you are wondering why this batch file has a .cmd rather than .bat file extension, see stackoverflow.com/questions/148968/windows-batch-files-bat-vs-cmd.

 

3. Create a key binding in config.py

In your config\config.py configuration file, add this line:

config.bind(',qenv', 'spawn -u -o "qb-env.cmd"')
                                👆
                                Note

If you do not have a config.py, which is qutebrowser’s configuration file, see Infinite Ink’s Getting Started with qutebrowser.

 

4. :config-source

To tell qutebrowser about this new ,qenv key binding, run the following from within qutebrowser:

:config-source

 

5. Launch qb-env.cmd from within qutebrowser

In qutebrowser, make sure you are in command mode by pressing the Esc key and then type:

,qenv

This will run qb-env.cmd and its output will be displayed in a new qutebrowser tab (thanks to the -⁠o argument specified in step 3 above).

 

💡
  • The -u spawn argument is equivalent to --userscript.

  • The -o spawn argument is equivalent to --output.

  • In qutebrowser v2.2.0+, you can use the :process command to display the full output of a spawn command in the current qutebrowser window.

 

Calling bash scripts from Windows “wrapper” userscripts

Calling a WSL bash script from a Windows userscript

I’d rather write a bash shell script than a Windows batch file and, thanks to WSL (Windows’ Subsystem for Linux),⁠[3] most of my Windows qutebrowser scripting is actually bash scripting. In this section, I briefly describe my tumblelog-⁠wrapper.cmd Windows userscript and my tumblelog.sh bash script that it calls.

 

Key binding in config.py

I put the following line in my config.py.

config.bind(',t', 'spawn -u tumblelog-wrapper.cmd')

This makes it possible to use ,t to launch my tumblelog-wrapper.cmd Windows userscript, which adds qutebrowser’s current web page to Infinite Ink’s #tumblelog Portal.

 

💡

When the argument to spawn -u is a relative path, it is relative to qutebrowser’s data\userscripts\ or config\userscripts\[4] directory. To put a userscript anywhere on your system, use an absolute path, for example:

config.bind(',t', 'spawn -u "C:\\Users\\USERNAME\\Sync\\qb\\tumblelog-wrapper.cmd"')

 

tumblelog-wrapper.cmd Windows userscript

In the Windows file system, my qutebrowser config\ directory⁠[5] contains userscripts\tumblelog-⁠wrapper.cmd, which comprises the following five lines.

@REM change code page so UTF-8 characters work
chcp 65001

@REM pass six QUTE_ variables to the bash script
wsl.exe /home/WSLUSERNAME/Scripts/tumblelog.sh "%QUTE_URL%" "%QUTE_TITLE%" "%QUTE_SELECTED_TEXT%" "%QUTE_COMMANDLINE_TEXT%" "%QUTE_HTML%" "%QUTE_TEXT%"

 

  • WSLUSERNAME is my WSL user name.

  • This tumblelog-wrapper.cmd Windows userscript does not work if any tumblelog.sh argument, for example %QUTE_TITLE%, contains an ASCII double quotation mark (").⁠[6]

 

tumblelog.sh bash script

In the WSL file system, my ~/Scripts/tumblelog.sh starts out like this:

#!/bin/bash

QURL=$1
QTITLE=$2
QSELECTED=$3
QCOMMANDLINE=$4
QHTMLPATH=`wslpath $5`
QTEXTPATH=`wslpath $6`

# below here, I use a heredoc to create a Hugo leaf bundle

I hope this is enough to get you started using a WSL bash script with qutebrowser.

 

Caveats

 

Calling a Git Bash script from a Windows userscript

Instead of calling a WSL script, you can call a Git Bash script by replacing the tumblelog-wrapper.cmd batch file in the previous section with something like the following.

tumblelog-wrapper.cmd (with absolute paths)
@REM The sh.exe below is part of Git For Windows
"C:\Program Files\Git\bin\sh.exe" -l "C:\full\path\to\tumblelog.sh"

If both sh.exe and tumblelog.sh are on your path, you can use the following.

tumblelog-wrapper.cmd (pathless)
@REM IMPORTANT: Make sure the sh.exe below is not a trojan!
"sh.exe" -l "tumblelog.sh"

 

 

See also

Endnotes


1. Many Infinite Ink articles, including this one, are evergreen and regularly updated.
2. Unless you have redefined these Windows environment variables.
3. It would probably make more sense if WSL were called LSW (Linux Subsystem for/of/on Windows), but it is not because, according to Rich Turner in this tweet, Microsoft “cannot name something leading with a trademark owned by someone else.” Rich’s tweet has inspired me to interpret the WSL acronym as meaning Windows Subsystem for Linux (notice the apostrophe ()).
4. In qutebrowser v1.14.1 and earlier, userscripts are in data/userscripts/. In v.2.0.0+, userscripts are in either data/userscripts/ or config/userscripts/ (or both).
5. To find out your qutebrowser config and data directories, run the :version command from within qutebrowser.
6. An ASCII quotation mark is also known as a dumb, neutral, vertical, straight, or typewriter quotation mark.

Comments and questions 📝 👍 👎 🤔

Your public comment or question might immediately improve this page or help me to (eventually) improve this page.