Skip to content

WSL Vim Integration Tutorial

Calvin edited this page Dec 30, 2021 · 1 revision

This page describes an integration which allows a Windows installation of Firefox to communicate with a WSL installation of Vim running on the same machine. This article is exclusively about editorcmd, but the more general idea is to share a single tridactylrc/vimrc across Windows and Linux. The author would like to convey their deepest sympathies to anyone who actually needs this.

This integration has three components: a Tridactyl autocommand which initializes this code, a Javascript editor invocation which reads the OS and writes a setting, and a Vimscript path/buffer manipulation which runs on editor start. It requires the native messenger (see :help nativeinstall), and it has been tested only against Windows 10, WSL2, and Vim 8.

Path Manipulation (Vimscript)

We will work backwards from the editor. This vimrc function is used to initialize Vim in the specific context of a Tridactyl editor call. If Tridactyl is running on Windows, Vim will receive a Windows path such as C:\Users\Satan\AppData\Local\Temp\.... In this case, we want to edit /mnt/c/Users/Satan/AppData/Local/Temp/... from WSL, which will leave an open buffer to a junk path. Regardless of the browser's OS, we'll use Tridactyl's handy line/column output to set the cursor position.

function Tridactyl(line, column, is_windows)
	if a:is_windows
		execute 'edit ' . expand('%') -> {path ->
			\ '/mnt/' . tolower(path[0]) . substitute(path[2:], '\\', '/', 'g')
			\ }()
		$-bdelete! " delete previous buffer
	endif
	call setcursorcharpos(a:line, a:column + 1)
endfunction

Note that the actual determination of whether Windows is involved is passed through the invocation rather than inferred from the path.

If you prefer to start in insert mode, you can use this column/cursor comparison to get consistent behavior if the cursor happens to be at the end of the line. Insert it before endfunction.

	if col('.') == col('$') - 1 " if cursor is on last column
		startinsert! " like :normal A
	else
		startinsert " like :normal i
	endif

Editor Invocation (JS)

Vim gets is invoked according to the Tridactyl setting editorcmd. We'll query the userAgent and wrap the editorcmd in a Windows Batch start if necessary. This tutorial assumes that the following Javascript will be saved to the same directory as the users' tridactylrc, with a filename such as wsl-integration.js:

// record the cold grip of .NET as 1 (true) or 0 (false)
let is_windows = + /Windows/.test(navigator.userAgent)

// for format-string details, see Tridactyl's `:help editor`
let invoke_vim = `vim '%f' -c 'call Tridactyl(%l, %c, ${is_windows})'`

// consider changing `bash` to your WSL distro, e.g. `debian` or `ubuntu`
tri.excmds.set("editorcmd", is_windows && `start bash -c "${invoke_vim}"` || invoke_vim)

Autocommand (Tridactyl Excmd)

An autocommand initializes our editorcmd on browser launch. The argument following autocmd TriStart is a JS regex used to match the hostname of the device. The pathname specified with -r is relative to your tridactylrc; again, this tutorial assumes both files are in the same directory.

autocmd TriStart .* composite source_quiet; js -r wsl-integration.js

Note: composite is used to avoid overwriting the default autocmd TriStart .* excmd, source_quiet.


You're done! Now you don't need to leave the comfort of Linux Vim in order to work for people who still use Sharepoint! Win win? See you in Hell.