3

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:

#!/bin/sh
    
export LIBGL_ALWAYS_INDIRECT=1
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"
/mnt/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. :(

Lord_Devi
  • 31
  • 3
  • Can 'wslpath` help you? – Tobias Jun 23 '20 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 '20 at 10:19
  • Did you try? Just pass the full windows file path to `wslpath` on WSL. – Tobias Jun 24 '20 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. – Terry Jun 25 '20 at 11:16
  • Thanks to Tobias I was able to get a lot closer. But still not quite there. :( – Lord_Devi Jul 01 '20 at 15:41
  • Could you perform the path translation in `runemacs.sh`? Like `setsid emacs $(wslpath -u $1)`? You'll need to leave off the `--file=` when you run it. – Mark Jul 02 '20 at 20:57
  • If you are running in powershell, you can use (..) as the equivalent of `` command expansion in bash. E.g. wsl -e emacs --file=(wsl -e wslpath...) – glucas Oct 01 '20 at 17:51

2 Answers2

1

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=127.0.0.1:0.0
FILENAME=$(wslpath -u "$1")
setsid /home/matt/opt/emacs/bin/emacs "$FILENAME"

In cmd.exe just type

runemacs.sh

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.

Percee
  • 143
  • 6
-1

Emacs has a native Windows release: https://www.gnu.org/software/emacs/download.html#nonfree

Perhaps it would be easier just to use it instead of jumping through hoops to run the Linux release?

db48x
  • 15,741
  • 1
  • 19
  • 23