Search code examples
powershellvimwindows-terminal

Using Vim's Terminal JSON API From pwsh / windows terminal


For when you are in Vim's :terminal buffer, and you want to open a new file, but use the existing Vim instance instead of create a new one, Vim has a specific escape sequence you can enter to tell Vim to do a command like open a file:

Job to Vim: JSON API ~
                            *terminal-api*
The job can send JSON to Vim, using a special escape sequence.  The JSON
encodes a command that Vim understands.  Example of such a message:
    <Esc>]51;["drop", "README.md"]<07>

But how do I enter these characters in windows terminal / pwsh?

Looks like I can use the api successfully from zsh (WSL) via the following:

 printf '\033]51;["drop", "README.md"]\07'

Solution

    • You're seeing an apparent limitation in the native Windows version of Vim (vim.exe) due to the specifics of Windows' VT (Virtual Terminal) support - and the limitation applies irrespective of whether you launch vim.exe stand-alone, from a conhost.exe window (regular console window), or from Windows Terminal:

    • By contrast, the Job-to-Vim escape sequence does work on Unix-like platforms, including when running Vim from inside WSL on Windows (/usr/bin/vim).

    The following describes how to emit such an escape sequence from PowerShell in principle, but for the reasons stated, it won't solve your problem in Windows Terminal / Windows console windows.


    In PowerShell (Core) 7.3+, from a Unix environment,

    printf '\033]51;["drop", "README.md"]\07'
    

    should work as-is.

    (In v7.2-, due to a long-standing bug, you'll have to escape the " chars. as \" - see this answer).


    The PowerShell-native v7+ equivalent - which works on all platforms - is (see the conceptual about_Special_Characters help topic):

    Write-Host -NoNewLine "`e]51;[`"drop`", `"README.md`"]`a"
    

    (In Windows PowerShell, escape sequence `e to produce an ESC char. isn't supported; use $([char] 27) instead.)

    Note that "`e]51;[`"drop`", `"README.md`"]`a" alone, using PowerShell's implicit output mechanism, would implicitly print a newline after the string value, hence the use of Write-Host -NoNewLine (alternatively, use [Console]::Write(...))