From Windows 10, how can I call an Emacs instance residing on a Windows 10 WSL 2 Linux install, passing it a given file to visit?

So far, I've done this:

On my WSL 2 Linux, I've created a script called runemacs.sh which I keep in ~/bin/

It sets some needed environment variables, to make libgl happy and to tell Emacs where my Windowds 10 X server is. It looks like this:

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
setsid emacs $1

I can then open a graphical Emacs client from Windows 10 using a command like the following from a Windows Powershell or Command prompt:

wsl -e /home/ld/bin/runemacs.sh

This brings up the Emacs graphical client on my windows desktop.

What I can't do, is then tell Emacs what file I want to edit. If I have a file named test.txt on my Windows 10 file system for example, I can't then run this to open that file in Windows:

 wsl -e /home/ld/bin/runemacs.sh --file=test.txt

It makes sense why this wouldn't work. I am basically telling Emacs to open test.txt on the WSL 2 Linux install. But this is as far as I've been able to figure out how to go myself.

How can I tell Emacs which file to edit?

UPDATE 1: I was able to get much further from Tobias's help. But I am still left unable to ultimately call wsl's emacs from Windows using 'wsl' combined with 'wslpath'.

I can call wslpath directly from wsl and get a correctly formatted path by doing the following from Windows:

PS C:\> wsl -e wslpath -u "d:\lorddevi\Documents\OpenBSD-Notes.md"

The 2nd line there being the output. Which, if I could pass to emacs on wsl, it would open fine.

However, I can't use command expansion quotes ( `` ) that I would normally use in a Bash script or on the command line, but can't from windows.

If I try to perform that expansion by creating a bash script on WSL in my homedir, and calling it from Windows, the slashes get trimmed from the pathname for some reason.

Such as:

PS C:> wsl ~/bin/wslemacs.sh d:\lorddevi\Documents\OpenBSD-Notes.md /mnt/d/lorddeviDocumentsOpenBSD-Notes.md

I can't use -e here as I normally would and still call a bash script I guess. I tried and it just quietly dies.

So I've tried everything at this point that I can think of to get wslpath to work for me. I am SO close.

If I could either:

  1. Use `` command expansion quotes for the wslpath call I could make this work.

  2. Or if I could call my 'wslemacs.sh c:\pathto\file.txt' script with windows' wsl.exe command I could also get this working I think.

But neither work, and i am once more lost. :(

  • Can 'wslpath` help you? – Tobias Jun 23 at 14:58
  • I don't think so. I think in order to even use wslpath at all, I would run into the same problem. How do I pass an option to wslpath that is a reference to a file not on the WSL subsystem? – Lord_Devi Jun 24 at 10:19
  • Did you try? Just pass the full windows file path to wslpath on WSL. – Tobias Jun 24 at 11:10
  • WSL is not an ideal system. I once installed Cygwin Emacs residing on Cygwin but then I removed it along with the Cygwin because of some incompatibility. Ive been using the native Windows Emacs ever since and never had any problems so far. Just my two cents. – Romario Jun 25 at 11:16
  • Thanks to Tobias I was able to get a lot closer. But still not quite there. :( – Lord_Devi Jul 1 at 15:41

This works on my WSL 2 with debian 10 and emacs 28.0.5

My batch script runemacs.bat(calling a few powershell commands inside):

@echo OFF

:: Get the given path to file
set givenPath=%*

:: Get absolute path to target file
for /f "delims=" %%a in ('powershell -Command "[System.IO.Path]::GetFullPath( '%givenPath%' )"') do @set resolvedPath=%%a

:: Double the backquotes in both the file path and the current dir path
for /f "delims=" %%a in ('powershell -Command "$a = '%resolvedPath%'; echo $a.replace('\', '\\');"') do @set resolvedPath=%%a
for /f "delims=" %%a in ('powershell -Command "$a = '%CD%'; echo $a.replace('\', '\\');"') do @set currentDirPath=%%a

:: Call bash script with backquotted paths
debian.exe run /home/myhome/bin/runemacs.sh "%resolvedPath%" "%currentDirPath%"

My bash script runemacs.sh:

#!/usr/bin/env bash

export DISPLAY=
FILENAME=$(wslpath -u "$1")
setsid /home/matt/opt/emacs/bin/emacs "$FILENAME"

In cmd.exe just type


to open emacs in the current directory, or

runemacs.sh file_or_dir_path

Where file_or_dir_path can be either relative or absolute.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.