启用双击资源管理器中的文件并在 Windows 终端中使用 WSL 应用程序(Neovim、Vim 等)启动/运行它的脚本

run*_*ace 5 windows vim batch-file neovim windows-subsystem-for-linux

我使用 WSL(适用于 Linux 的 Windows 子系统)。我在 WSL 中安装了 Neovim/Vim/etc,并希望能够在资源管理器中打开一个文件,并在 Windows 终端内在 WSL 中安装的 Neovim 中打开它。编写什么脚本来启动它,我正在努力从cmd, 通过 wt.exe转义双引号,然后转入 WSL bash。

为 windows 和 linux 配置两个版本的 Neovim/Vim 可能会很痛苦。而只是在 Windows 和 WSL 中仅使用 WSL 版本。

run*_*ace 5

TL; 博士

将文件类型与运行此批处理脚本相关联(相应地设置myapp):

@echo off
set my_app=nvim
set my_wt_profile="Ubuntu-20.04"
set pp=%1
set pp=%pp:'='\''%
set pp=%pp:;=\;%
set launch="p=$(wslpath '%pp:"=%') && cd \\"^""$(dirname \\"^""$p\\"^"")\\"^"" && %my_app% \\"^""$p\\"^""
start wt.exe new-tab -p %my_wt_profile% bash -i -c %launch%
Run Code Online (Sandbox Code Playgroud)

脚本的github repo

介绍

不幸的是,无法将 powershell 脚本与文件类型(通过open with? choose another app? Look for another app on this pc)相关联。选择编写一个批处理文件,并将所有逻辑放在那里。在文件加载时创建 bash 脚本或 vim 插件会更容易,但是这个难题的两个部分需要彼此同步。

执行以下步骤:

  1. 创建一个批处理文件并粘贴以下代码(我们将此脚本称为“启动脚本”,我将其命名为wsl_nvim.bat):

注意:以下代码与 TL;DR 版本相同,但有注释:

:: This batch script is ment to be associated with file types, such that when
:: the associated file type is opened, it calls this script.
:: This script then open it with Neovim within WSL in a windows terminal (wt).


:: If require a " in the bash command, escape it with \\"^""
:: Example1: To print in bash via cmd the following string: hel'lo
:: bash -i -c "echo "^""hel'lo"^"" "
:: Example2: To print in bash via cmd via wt.exe: hel'lo
:: wt.exe new-tab -p "Command Prompt" cmd /k bash -i -c "echo \\"^""hel'lo\\"^"" "
::
:: To cd to the parent dir: cd "$(dirname "$p")"
:: Escaping it becomes:     cd \"^""$(dirname \"^""$p\"^"")\"^""

@echo off

:: === REQUIRED CUSTOM VALUES ==================================================

:: The name of the WSL app to run
set my_app=nvim

:: The name of your windows terminal linux profile, open the windows terminal
:: settings file and file the linx profile name, e.g.: "name": "Ubuntu-20.04",
set my_wt_profile="Ubuntu-20.04"

:: =============================================================================

:: Windows passes in the filepath in double quotes, e.g.: "C:\Users\Michael\foo.txt"
set pp=%1

:: We passing the path into bash, which has $ and \, so we pass within single quotes
:: so all chars will be taken literally, except the single quote, which we can
:: escape with '\''
set pp=%pp:'='\''%

:: When wt.exe interprets the string, need to escape the semicolon with \;
set pp=%pp:;=\;%

:: Launch basically does: pass in $p, get wslpath of $p, then cd to the dir
:: of the wslpath, then open wslpath with nvim.
:: wslpath requires the input to be within single quotes, or else it will fail.
:: full wt.exe path: %LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe
:: GIANT GOTCHA! Can only strip outter double quotes from %pp% if placing within
:: double quotes, else special chars will be interpretted literally, e.g. ^ will escape.
set launch="p=$(wslpath '%pp:"=%') && cd \\"^""$(dirname \\"^""$p\\"^"")\\"^"" && %my_app% \\"^""$p\\"^""

:: Use `start` to launch cmd and cleanup/close the parent process immediately.
:: bash -i starts bash interactively.
:: bash -c "long command" start bash and allow one to pass in a command to run.
start wt.exe new-tab -p %my_wt_profile% bash -i -c %launch%
Run Code Online (Sandbox Code Playgroud)

奖励 1 - 将“启动脚本”与文本文件类型相关联

让我们将批处理脚本作为 explorer.exe 的右键单击选项中的一个选项Open with提供。下Open with一个可能必须选择choose another app并向下滚动,这比为每种新文件类型寻找批处理脚本的文件系统要容易得多。

执行以下步骤:

  1. 复制以下批处理脚本并将其粘贴到与上述脚本相同的目录中的文件中。
  2. 将 的值更改myscript为指向您选择的“启动脚本”名称。
  3. 保存并关闭批处理脚本。
  4. 右键单击批处理脚本并选择 Run as administrator
:: This batch script associates the files in %list% with the `txtfile` type, and
:: changes the `txtfile` type to open with with %myscrip%.
:: It does not make it the default app.
:: One can't programmatically change the default file association of an already
:: associated filetype in Windows 10 after the first login without the gui,
:: this is by design for security.

@echo off
echo !!! THIS SCRIPT MUST BE RUN AS ADMIN !!!

:: === CUSTOM VALUES START =====================================================

:: A space separated list of extensions to be associated with the `txtfile` type
set list=css gitignore html ini js json lua log markdown md php py render sass scss template text txt xml

:: Set myscript to the double quote filepath of the script to run
:: %~dp0 is the dir of this script file
set myscript="%~dp0wsl_nvim.bat"

:: === CUSTOM VALUES END =======================================================

:: e.g. require the same as if one typed into cmd: ftype txtfile="C:\current dir\wsl_nvim.bat" "%1"
echo:
echo Create a `ftype` called `txtfile` and assign it to run with WSL NVIM:"
ftype txtfile=%myscript% "%%1"

echo:
echo `ftype` set for `txtfile`, let's check its set:
ftype | findstr "txtfile"

echo:
echo Create a `assoc` between extensions in %list% with `txtfile`
(for %%a in (%list%) do (
   assoc .%%a=txtfile
))

echo:
echo `assoc` set for each extension, lets check `assoc`:
assoc | findstr ".txt"

echo:
echo Now if you right click on one of these file extensions, and select `Open with`,
echo and select `choose another app`, it should list %myscript% there.
echo SCRIPT COMPLETE.
pause
Run Code Online (Sandbox Code Playgroud)

奖励 2 - 创建任务栏快捷方式

  1. 复制“启动脚本”路径。
  2. 在资源管理器中右键单击NewShortcut.
  3. 输入一个合适的名称,例如 WSL NVIM
  4. 现在,如果右键单击新创建的快捷方式,则无法选择固定到任务栏或启动。
  5. 右键单击快捷方式,选择Propertiestarget字段并将其更改为(确保自定义两个路径!):
    cmd.exe /s /c ""C:\path\to\launch\script\wsl_nvim.bat" "\\wsl$\Ubuntu-20.04\desirable\default\location\temp_filename""
    
    Run Code Online (Sandbox Code Playgroud) 对我来说,上面看起来像:
    cmd.exe /s /c ""C:\code\software_setup\utils\wsl_nvim.bat" "\\wsl$\Ubuntu-20.04\home\michael\temp""
    
    Run Code Online (Sandbox Code Playgroud)

现在,如果您双击快捷方式,它应该会在给定位置打开带有空白文件的 wsl 应用程序,并带有临时文件名(取决于您的应用程序处理路径的方式)。您现在可以右键单击快捷方式并将其固定到任务栏或开始菜单。