glacambre / firenvim

Embed Neovim in Chrome, Firefox & others.
GNU General Public License v3.0
4.69k stars 145 forks source link

s:get_runtime_dir_path function returns garbage when WSLg is activated on Windows 11 #1458

Closed SuperSandro2000 closed 1 year ago

SuperSandro2000 commented 1 year ago

What I tried to do

Run the post install script via call firenvim#install(0) in my WSL with NixOS on Windows 11 with WSLg enabled.

What happened

Because $XDG_RUNTIME_DIR is set to /mnt/wslg/runtime-dir the header of the generated bat script contained the following:

@echo off
mkdir "WSLG:/runtime-dir\firenvim" 2>nul
cd "WSLG:/runtime-dir\firenvim"

which is obvious garbage and wont work.

When unsetting XDG_RUNTIME_DIR before opening neovim and cleaning up the windows file the installation went through smoothly.

glacambre commented 1 year ago

Thanks for opening this issue. Can you confirm that I understood everything correctly?

SuperSandro2000 commented 1 year ago

Yes, correct.

glacambre commented 1 year ago

I'm not sure how to fix this. The source of the issue is to_windows_path: https://github.com/glacambre/firenvim/blob/eeaddd0b503f841fa24f60cebd14fa93d2b33f77/autoload/firenvim.vim#L73-L79

There's an expectation that the path is of the form /mnt/$DRIVE_LETTER/some/more/directories, which is what WSL does by default AFAIK. It seems you created your own mount point, which might be pointing to somewhere else entirely.

Do you know how to figure out what windows directory a wsl mount point is pointing to?

SuperSandro2000 commented 1 year ago

It seems you created your own mount point

No, that is the default mountpoint for wslg. AFAIK it is a network share to allow wslg to do easier x11 forwarding by moving the sockets to that directory..

Do you know how to figure out what windows directory a wsl mount point is pointing to?

It can be accessed from windows via a network drive, not directly since it is a virtual drive.

$ wslpath -w /mnt/wslg/runtime-dir/
\\wsl.localhost\NixOS\mnt\wslg\runtime-dir
SuperSandro2000 commented 1 year ago

It can be accessed from windows via a network drive

but cmd cannot cd into that directoy. We could use pushd but then WSL cannot translate the path.

To where should that path normally point in WSL? Something like?

mkdir "C:\Users\User\AppData\Local\Temp\firenvim" 2>nul
cd "C:\Users\User\AppData\Local\Temp\firenvim"
glacambre commented 1 year ago

The following patch should solve everything:

diff --git a/autoload/firenvim.vim b/autoload/firenvim.vim
index e658532..94cd4e0 100644
--- a/autoload/firenvim.vim
+++ b/autoload/firenvim.vim
@@ -590,6 +590,14 @@ function! s:get_executable_content(data_dir, prolog) abort
                                         \"let g:firenvim_c=stdioopen({'on_stdin':{i,d,e->g:Firenvim_oi(i,d,e)},'on_print':{t->g:Firenvim_oo(t)}})".
                                         \'"'
         endif
+   if s:is_wsl
+       " Get path of firenvim script on the linux side, execute that
+       " from the windows batch script
+       let s:is_wsl = v:false
+       let l:script_path = s:get_firenvim_script_path()
+       let s:is_wsl = v:true
+       return "@echo off\r\nwsl \"" . l:script_path . '"'
+   endif
         if has('win32') || s:is_wsl
                 let l:wsl_prefix = ''
                 if s:is_wsl
@@ -752,6 +760,10 @@ function! s:get_browser_configuration() abort

 endfunction

+function! s:get_firenvim_script_path()
+   return s:build_path([s:get_data_dir_path(), s:get_executable_name()])
+endfunction
+
 " At first, is_wsl is set to false, even on WSL. This lets us install firenvim
 " on the wsl side, in case people want to use a wsl browser.
 " Then, we set is_wsl to true if we're on wsl and launch firenvim#install
@@ -795,14 +807,10 @@ function! firenvim#install(...) abort
                 endif
         endif

-        " Decide where the script responsible for starting neovim should be
-        let l:data_dir = s:get_data_dir_path()
-        let l:execute_nvim_path = s:build_path([l:data_dir, s:get_executable_name()])
-
-        " Write said script to said path
+        let l:execute_nvim_path = s:get_firenvim_script_path()
         let l:execute_nvim = s:get_executable_content(s:get_runtime_dir_path(), l:script_prolog)

-        call s:maybe_execute('mkdir', l:data_dir, 'p', 0700)
+        call s:maybe_execute('mkdir', s:get_data_dir_path(), 'p', 0700)
         if s:is_wsl
                 let l:execute_nvim_path = s:to_wsl_path(l:execute_nvim_path)
         endif

I'll open a PR and see if anything breaks.

glacambre commented 1 year ago

CI was okay with the change, so I merged it. Could you update the firenvim neovim plugin to master/f6ef690 , run firenvim#install() again and let me know if firenvim is working for you?

SuperSandro2000 commented 1 year ago

Inside of WSL things are now working like a charm when reinstalling without any other changes

echo 'abcde{}' | "/home/sandro/.local/share/firenvim/firenvim"
%{"messages": [], "version": "0.2.14"}

but from the cmd it is still not working and the prompt is staying open:

C:\Users\user>echo 'abcde{}' | wsl "/home/sandro/.local/share/firenvim/firenvim"

When adding the snipped from https://github.com/glacambre/firenvim/issues/1460#issuecomment-1303996406 then the prompt closes instead with no output.

The browser extension still show the same error Neovim died without answering..

I tried restarting chrome but that also did not fix things.

glacambre commented 1 year ago

Do you have multiple wsl machines installed? If yes, please try to install Firenvim in all of them - windows might be using the wrong wsl VM.

Also, if you go to chrome://extensions, enable developer mode (top right toggle) and click on the Errors button for Firenvim, do you get anything? (aside from a message complaining about manifest v2)

SuperSandro2000 commented 1 year ago

When I only start wsl then NixOS is started which is the default WSL instance.

The first two messages where errors, the last two only warnings.

_generated_background_page.html:1 Uncaught (in promise) Neovim died without answering.
Promise.then (async)
updateSettings @ background.ts:159
updateSettings @ background.ts:315
(anonymous) @ background.ts:326
onMessage @ browser-polyfill.js:1
_generated_background_page.html:1 Unchecked runtime.lastError: Error when communicating with the native messaging host.
background.ts:52 Current tab is undefined - failing to updateIcon()
updateIcon @ background.ts:52
await in updateIcon (async)
(anonymous) @ background.ts:93
background.ts:52 Current tab is undefined - failing to updateIcon()
updateIcon @ background.ts:52
await in updateIcon (async)
(anonymous) @ background.ts:117
glacambre commented 1 year ago

Everything looks as expected here... Do you have a windows registry key named HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim? If yes, what is it pointing to?

Also, could you add something like echo 1 >> /tmp/script, echo 2 >> /tmp/script, echo 3 >> /tmp/script on every other line of /home/sandro/.local/share/firenvim/firenvim, then run the firenvim script with echo 'abcde{}' | wsl "/home/sandro/.local/share/firenvim/firenvim" from cmd.exe and let me know where the script's execution stops?

SuperSandro2000 commented 1 year ago

Do you have a windows registry key named HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim? If yes, what is it pointing to?

Yes, C:\Users\user\AppData\Local\firenvim\firenvim-chrome.json

Also, could you add something like echo 1 >> /tmp/script, echo 2 >> /tmp/script, echo 3 >> /tmp/script on every other line of /home/sandro/.local/share/firenvim/firenvim, then run the firenvim script with echo 'abcde{}' | wsl "/home/sandro/.local/share/firenvim/firenvim" from cmd.exe and let me know where the script's execution stops?

I tried that and when just executing wsl "/home/sandro/.local/share/firenvim/firenvim" it also went through to nvim but when adding the pipe nothing was executed. Even when chagning the shebang to garbage nothing happened. I am not sure how much this is related to NixOS-WSL.

glacambre commented 1 year ago

I tried that and when just executing wsl "/home/sandro/.local/share/firenvim/firenvim" it also went through to nvim but when adding the pipe nothing was executed. Even when chagning the shebang to garbage nothing happened. I am not sure how much this is related to NixOS-WSL.

Did you look at the content of /tmp/script? The echo lines are redirecting their output to that file.

SuperSandro2000 commented 1 year ago

When executing inside of WSL all the temporary echos I placed in the file where written into /tmp/script. That still happened when executing from windows without the pipe but as soon as I tried to pipe into wsl nothing was written into /tmp/script anymore. I removed the file between tests.

glacambre commented 1 year ago

Okay, thanks for trying this. What happens if you remove /tmp/script, restart chrome and then attempt to use firenvim by e.g. going to http://txti.es and clicking on the textarea? Is /tmp/script created? Does it contain the same lines as when running from a wsl shell?

SuperSandro2000 commented 1 year ago

Is /tmp/script created?

Nope

Does it contain the same lines as when running from a wsl shell?

Nothing is in it.

I think the problem is somehow the piping. cmd has pipes, too but they are very different to unix pipes and I am not sure if you can even pipe into WSL like you are doing. I tried the extension in Firefox on Linux with the same NixOS setup and got the extension working but still requiring some configuration.

glacambre commented 1 year ago

I think the problem is somehow the piping. cmd has pipes, too but they are very different to unix pipes and I am not sure if you can even pipe into WSL like you are doing.

Piping does not come into play when running firenvim.bat from the browser, stdin/stdout are inherited by whatever command is ran by the batch script, and neovim inherints said stdin/stdout when exec is called in the bash script.

In general, there is no fundamental issue with how Firenvim currently works: Firenvim is known to work with both WSL (#839, #918, #969, #1198) and NixOS (#175, #365, #422, #960).

I tried the extension in Firefox on Linux with the same NixOS setup and got the extension working but still requiring some configuration.

You are very likely to need the same configuration in your WSL machine then. Could you try to make your WSL-nixos configuration match your linux-nixos configuration and try again?

SuperSandro2000 commented 1 year ago

My WSL machines have generally almost the same configuration, biggest difference is the removal of the desktop environment. Also the extension can communicate at least a little with neovim because it can figure out the version of the extension image

Wow, it now works! I think it might have to do something with NixOS-WSL fixing some init related problems recently.