winpty
winpty copied to clipboard
Using winpty with neovim
Hi, let me start with a bit of background:
libvterm is an abstract terminal emulator library without any system dependencies(implemented in pure C99 API). It exposes a structure that keeps track of terminal state and updates the screen when it receives terminal output(fed by the user).
One program that uses this library to implement an embedded terminal emulator is neovim. ATM neovim is only officially supported on UNIX, but some community members are porting it to windows.
When running under windows, neovim spawns a program with libuv, which in turns calls windows CreateProcess API to spawn and communicate with children, transfering bytes from/to their stdio into the abstract terminal emulator. While this doesn't work with native windows console programs, I wanted to try using winpty unix adapter to make neovim fully capable of running its terminal emulator on windows.
I have some questions about winpty:
- Do we need anything other than winpty unix adapter(
console.exe
) in order to "convert" windows console programs into the "unix format"? In other words, just spawningconsole.exe
usingCreateProcess
(and proper stdio redirection) is enough to make it create a hidden console window and forward esc codes to the parent process? - How do we notify programs running under
console.exe
that window dimensions have changed?
If neovim is using a terminal emulator, am I right in assuming that neovim is a graphical program rather than terminal/console?
The console.exe
program is a Cygwin/MSYS program (as opposed to winpty.dll
, winpty-agent.exe
, and winpty-debugserver.exe
, which are normal Windows binaries compiled with either MinGW or MSVC). From reading https://github.com/neovim/neovim/issues/1749, it seems clear that neovim is targeting normal Windows, so console.exe
probably won't work as-is. (I suppose in principle, neovim.exe could redistribute parts of Cygwin, but even then, console.exe
expects stdin/stdout to be ptys, so it will complain if neovim starts console.exe
with ordinary Windows pipes.)
FWIW: console.exe
detects window dimension changes using SIGWINCH
signals, which of course don't exist on Windows, but do exist on Unix, so Cygwin emulates them somehow. console.exe
calls winpty_set_size
when it detects the resize ([1] [2]).
I suppose console.exe
could be modified to do normal Windows I/O. The JOE integration I linked below did something like this.
It might make more sense to spawn winpty-agent.exe
rather than console.exe
. console.exe
isn't doing much besides copying bytes between stdin/stdout and the agent's pipe(s).
Invoking console.exe
is almost what you want, so maybe something like that ought to work. Communicating a changed terminal size seems to be the biggest sticking point. I can think of a few ways to do it, but they've all got issues of their own:
- Named pipes (Maybe neovim generates a unique and hard-to-guess pipe name, then the winpty EXE connects to the pipe and receives messages).
- Anonymous pipes (neovim calls
CreatePipe
and passes the handle on the command-line. Either the handle is inheritable or the winpty EXE usesDuplicateHandle(DUPLICATE_CLOSE_SOURCE)
to take the handle away from the parent. - HWND messages? Idle speculation: I suppose the winpty EXE would own the window; maybe neovim would generate a random window caption, then use
FindWindow
to locate it? What happens if the winpty program dies, and the HWND is recycled just before neovim sends its message?
When Windows neovim spawns a child process, it needs to ensure that it doesn't create a visible console window. IIRC, both console.exe
and winpty-agent.exe
are marked CONSOLE subsystem, not WINDOWS subsystem. If neovim is WINDOWS, and it uses CreateProcess to spawn a CONSOLE program, then Windows will default to creating a new console (with a corresponding console window).
Also, if you do decide to link against winpty.dll
, you might want to use the newer API, currently in the libwinpty-rewrite branch. The API on master has some problems. The biggest difference is that the old API had a winpty_get_data_pipe
function returning an overlapped full-duplex named pipe handle, which required API clients to do asynchronous I/O. The new API instead has functions that return pipe names, which the API client can open using any method. e.g. neovim could use uv_pipe_connect
. Unfortunately, this new API isn't quite done yet, which is why it's not merged into master.
I'm willing to help more with this, because my current project is figuring out how to make winpty easier to embed (as well as merging some changes from pty4j's winpty fork).
If it helps, winpty is integrated into these other projects:
- pty4j (used by IntelliJ), uses a winpty fork.
- Eclipse's "TM Terminal" via CDT.
- JOE's Own Editor. (I haven't tested this code at all.)
-
pty.js project, uses a winpty fork. The last time I looked, this code didn't compile. What's interesting is that pty.js is a node.js module, which uses libuv. This winpty fork bypassed
winpty_get_data_pipe
for easier libuv integration.
PostThreadMessage
looks like it'd work, except that it needs the thread handle returned from CreateProcess
, and libuv closes the thread handle. AFAICT, there is no practical way to reopen the thread handle.
@rprichard thanks for the insight. FWIW there's a branch where @equalsraf tried winpty unix adapter and it returned 10, which I assume is because the adapter needs to be spawned through msys/cygwin API.
If neovim is using a terminal emulator, am I right in assuming that neovim is a graphical program rather than terminal/console?
More or less. ATM neovim is a text program, but it can also start in a daemon mode where arbitrary UI clients can connect and display its font grid(which is how the windows version works), but for winpty this is irrelevant since the terminal is inside a neovim window(which as far as the UI is concerned, is just another text window)
From your comment, I think there are two reasonable ways that neovim can use winpty:
- Link against libwinpty(which I assume takes care of transparently spawning and communicating with the agent) and use it to implement neovim pty layer on Windows. This seems the more correct approach since it avoids the overhead of passing data through a bridge process, and libwinpty exposes API for changing the console dimensions(and we would not need to emulate SIGWINCH/ioctl calls in any way). basically we'd need a pty_process.c version for windows that uses libwinpty API to spawn process and pass the stdio handles to libuv for polling. The disadvantage of this path is that it requires more work.
- Implement (or adapt) a program like console.exe that works when spawned from the
CreateProcess
API. This seems like the easiest path and would probably work with @equalsraf branch unmodified (with the exception of changing console dimensions).
What would be the way to go, considering that we want to spawn not only windows-native console programs such as cmd.exe/powershell.exe, but also msys programs like bash.exe(BTW do we need to use msys API in order to spawn bash.exe from neovim?)
I also have a few more questions about winpty:
- Would it be possible to adapt the existing console.exe so that it works when spawned from msys API(mintty) and from
CreateProcess
API? Clearly we'd need another way to control console dimensions, but this can be dealt with later. - Do you think it would be possible to build just libwinpty(which I assume doesn't depend on msys) with microsoft compilers?
- You mentioned we could just spawn winpty-agent.exe and communicate with it. Does that mean that there's one agent per console process and we can just send/receive data to/from its stdio(as opposed to using some protocol or named pipes)? I ask this because if there's some protocol or special named pipe usage, then it is probably best to use libwinpty API to communicate with the agent right?(Please disregard if I didn't understand how winpty works)
I'm willing to help more with this, because my current project is figuring out how to make winpty easier to embed (as well as merging some changes from pty4j's winpty fork).
I appreciate this and would love to see winpty with an easier embed interface. If you are interested seeing how neovim manages processes and help with libwinpty integration, here's a short summary:
- libuv_process.c implements process spawning through libuv API. This module is common to both windows and unix since libuv takes care of the abstraction.
-
pty_process.c is a UNIX-only module that uses
forkpty()
to spawn processes with pty file descriptors(the master side on Neovim). For changing console dimensions it usesioctl
(TIOCSWINSZ
). When a pty process is spawned, we take its associated file descriptors to libuv for polling(in the end the stream API is used to abstract reading/writing from both pty and normal pipes) -
process.c keeps track of all processes and implements the common API and delegates specialized calls to
libuv_process.c
/pty_process.c
.
As I mentioned above, I think implementing a pty_process_windows.c
module is the way to go but I'm not sure it is possible to pass the handles returned by libwinpty to libuv. Would you mind taking a look at pty_process.c
to see how well its API could map to libwinpty?(it is a very short module, about 250 loc)
FWIW there's a branch where @equalsraf tried winpty unix adapter and it returned 10, which I assume is because the adapter needs to be spawned through msys/cygwin API.
That sounds plausible. I would expect neovim to fail because console.exe
would link to a DLL like cygwin1.dll
or msys-2.0.dll
, which wouldn't be in the PATH. (Or, if it were in PATH, it'd write input is not a tty
or output is not a tty
to stderr, then exit with 1.)
From your comment, I think there are two reasonable ways that neovim can use winpty: ...
I think either method you've listed would work. The second approach seems simpler at the moment. I think I'll take a closer look in the next several days and see what's involved in both approaches.
libwinpty transparently spawns winpty-agent.exe
processes. It's careful to avoid leaking inheritable handles (by passing bInheritHandles=FALSE
to CreateProcess
), and it uses SW_HIDE
and/or puts the agent process onto a background window station / desktop. The background window station is required on at least XP and Vista so that the polling technique doesn't interfere with visible console windows.
Windows itself only allows a process to be attached to one console at a time, so there's a separate winpty-agent.exe
process for each console. Each console can have many processes attached, but typically the agent spawns only one parent process. (On the master branch, the agent never spawns more than one process.) The program using libwinpty can create multiple winpty_t
instances, which would spawn multiple agent processes.
- Would it be possible to adapt the existing console.exe so that it works when spawned from msys API(mintty) and from CreateProcess API? Clearly we'd need another way to control console dimensions, but this can be dealt with later.
I think console.exe
can be adapted so that it works without msys (while providing some other way to change the terminal size). I think the mode switch would need to happen at compile-time rather than run-time.
- Do you think it would be possible to build just libwinpty(which I assume doesn't depend on msys) with microsoft compilers?
Yes, libwinpty doesn't needs Cygwin or MSYS, and it's always compiled as a normal Windows program. MinGW produces normal Windows binaries, as does Microsoft Visual C++. While winpty's Makefile uses MinGW, there's also a src/winpty.gyp
file that can generate MSVC project files for all of the binaries except for console.exe
. To use it, download gyp and run <path-to-gyp>/gyp winpty.gyp
.
- You mentioned we could just spawn winpty-agent.exe and communicate with it. Does that mean that there's one agent per console process and we can just send/receive data to/from its stdio(as opposed to using some protocol or named pipes)? I ask this because if there's some protocol or special named pipe usage, then it is probably best to use libwinpty API to communicate with the agent right?(Please disregard if I didn't understand how winpty works)
Currently, the winpty-agent.exe
protocol is:
- libwinpty generates two pipe filenames (control and data) and creates two named pipes.
- libwinpty invokes
winpty-agent.exe
and passes it the pipe names and initial console size, e.g.:
"C:\cygwin\usr\local\bin\winpty-agent.exe" \\.\pipe\winpty-5956-1-control \\.\pipe\winpty-5956-1-data 165 62
- The agent connects to the two named pipes.
-
console.exe
uses libwinpty to do RPCs to the agent over the control pipe. It uses an RPC to spawn the initial child process and another RPC to update the terminal size.
The protocol in the libwinpty-rewrite branch is similar; the data' pipe is replaced with
coninand
conout` pipes, and the agent creates them rather than libwinpty.
In principle, though, winpty-agent.exe
could instead communicate terminal data over stdio. The initial child process could be passed on the command-line. (Doing so would reduce the maximum command-line, though.)
As I mentioned above, I think implementing a pty_process_windows.c module is the way to go but I'm not sure it is possible to pass the handles returned by libwinpty to libuv. Would you mind taking a look at pty_process.c to see how well its API could map to libwinpty?(it is a very short module, about 250 loc)
Sure, I'll take a look in the next few days.
I'm still planning to look at this, but it could be a few weeks.
@rprichard take your time, I'm just grateful that you are willing to help us :smile:
I prototyped a neovim<->winpty integration using winpty.dll
. I'm not sure it's the right way to do the integration -- invoking something like console.exe
might be better, but it's a start anyway.
It's at:
- https://github.com/rprichard/neovim/tree/rp-winpty
- https://github.com/rprichard/winpty/tree/neovim-demo
(The FindWinpty.cmake
file I wrote expects to find winpty.dll
/winpty.lib
in winpty's build
directory, so winpty should be built using Cygwin or MSYS. The winpty.dll
file is not a Cygwin/MSYS binary, though -- it's compiled using MinGW. A more proper build system would involve third-party
somehow and maybe do something with src/winpty.gyp
?)
The most interesting file is: pty_process_win.c
It has a problem where it doesn't capture all of the child's output after it's exited, and it always invokes cmd.exe
, ignoring the argv
and quote_cmd
fields in Process
.
I prototyped a neovim<->winpty integration using winpty.dll. I'm not sure it's the right way to do the integration -- invoking something like console.exe might be better, but it's a start anyway.
@rprichard you did much more than I could have hoped for, thank you!
What is the purpose of the neovim-demo tree? Did you have to make changes in order for winpty to work with neovim?(The diff from master is 6k lines so I couldn't tell).
A more proper build system would involve third-party somehow and maybe do something with src/winpty.gyp?)
I think so. Can winpty be built with microsoft compiler in case we want to generate a visual studio project? If so I might even port src/winpty.gyp to cmake so we can build without python.
The most interesting file is: pty_process_win.c
Nice! Did you manage to build this branch and/or test the :terminal
command on windows?
It has a problem where it doesn't capture all of the child's output after it's exited, and it always invokes cmd.exe, ignoring the argv and quote_cmd fields in Process.
You already did more than enough, I'm going to dig into pty_process_win.c and make any necessary adjustments. Thanks again!
What is the purpose of the neovim-demo tree? Did you have to make changes in order for winpty to work with neovim?(The diff from master is 6k lines so I couldn't tell).
At the moment, the neovim-demo branch is the same as the libwinpty-rewrite branch, which I was working on just before this issue was opened. There are a lot of changes on that branch relative to master -- it more-or-less rewrites winpty.dll
with a different API. I think its API is an improvement over the master branch API, probably. That branch has many non-API-related changes, too -- e.g. the first commit in the branch switches from C++98 to C++11 in addition to replacing a huge amount of code. In the near-term, I'm thinking I'm going to cherry-pick parts of libwinpty-rewrite into master, then rebase libwinpty-rewrite.
A more proper build system would involve third-party somehow and maybe do something with src/winpty.gyp?)
I think so. Can winpty be built with microsoft compiler in case we want to generate a visual studio project? If so I might even port src/winpty.gyp to cmake so we can build without python.
Yes, winpty definitely works with MSVC. MSVC 2013 should be new enough. My impression is that neovim is using MSVC 2015, which is good because it has much better support for C++11/14. (I'm trying to keep winpty working with MSVC 2013 and above, but I'd prefer to require MSVC 2015.)
I'm not sure I'm interested in adding a cmake file, but obviously you're free to create one. If I added one to this repo, I'd probably remove the gyp file. I noticed that neovim depends on libuv, which also uses gyp. libuv has a vcbuild.bat
file that downloads gyp. It clones master
from https://chromium.googlesource.com/external/gyp.
The most interesting file is: pty_process_win.c
Nice! Did you manage to build this branch and/or test the :terminal command on windows?
Indeed! The :terminal
command worked on Windows. Terminal resizing worked, too, IIRC.
This look awesome. Thanks @rprichard.
I cleaned up that FindWinpty.cmake a bit (its just as easy to drop the winpty files in .deps/usr) and it should be a bit more verbose now if it fails to find any of the files.
@tarruda we can write a bit of CMake to build in third-party, but I have already tested and I was able to link against the DLL from MSVC and MinGW builds, so maybe we can download binary builds instead of building from source. My work branch is here - ~~https://github.com/equalsraf/neovim/commits/tb-staging-winpty~~ (moved into neovim/neovim#810) - other than minor fixes there are no differences.
@tarruda we can write a bit of CMake to build in third-party, but I have already tested and I was able to link against the DLL from MSVC and MinGW builds, so maybe we can download binary builds instead of building from source. My work branch is here - https://github.com/equalsraf/neovim/commits/tb-staging-winpty (moved into neovim/neovim#810) - other than minor fixes there are no differences.
@equalsraf great! I built rp-winpty branch locally in msys2 but neovim aborted when term:
was invoked. It seems a libuv failed assertion was the cause. Since @rprichard managed to build and run locally, I assume this could be caused by building with mingw(I dont have visual studio installed so I couldnt test)
If you publish a prebuilt bundle of nvim + nvim-qt + winpty let me know, I've been wanting to run powershell in nvim for some time :)
The builds in 810 from appveyor already have neovim+winpty. https://ci.appveyor.com/project/equalsraf/neovim/branch/tb-mingw
You can get neovim-qt from its release page https://github.com/equalsraf/neovim-qt/releases
@rprichard, (bit off-topic; at the risk of it being inapplicable here) if we capture the device contexts of any Windows application via win32 API, we can get info about (and even modify) its graphical formation. I fiddled with this kind of thing once in Win2k days; captured a notepad's hDC to project its events onto another instance of notepad (mirroring all events including the user inputs). This was done as part of experimenting a custom remote desktop projection, in a server-client model. One thing I still remember is; as soon as the target application is minimized, the graphics handle goes haywire (all events go off). Although it is very low-level stuff and might not work seamlessly right off the bat (and worth the effort neither); just wanted to highlight the fact that with tooth and nail effort, it might be possible for consumers to build a resize event listener using win32 API without polling. Nonetheless, I think libcurses already provides SIGWINCH
equivalent implementation on Windows.
@am11 I'm not sure how device contexts (HDC) would alleviate polling. Can you refer to specific APIs? I'm guessing the idea is that winpty would somehow intercept drawing activity? The console is always hidden somehow. Currently it's always on a special window station / desktop.
The Console WinEvents API might allow winpty to stop polling for changes on Win7 and up. (https://github.com/rprichard/winpty/issues/46).
Nonetheless, I think libcurses already provides SIGWINCH equivalent implementation on Windows.
libcurses is designed for terminal/console programs. For such programs, it's easy to detect console size changes w/o polling. Just use ReadConsoleInput
, looking for WINDOW_BUFFER_SIZE_RECORD
records, with the ENABLE_WINDOW_INPUT
mode flag enabled. I would guess that's how SIGWINCH
is emulated on Windows.
@rprichard, I have that doodlebug project buried in some external hard drive. I will try to locate it and post more info to #46 if I find it. If memory serves; I think we were able to workaround polling by getting some semaphore about the target application's graphics state, and subscribed to some OS signal.
I'm guessing the idea is that winpty would somehow intercept drawing activity?
Yes, the idea was to be able to intercept graphics context of a PC game, capture its graphical state, encode it in a low bit-rate JPEG or likes and transmit it over the network (flash app in browser, where user's click coordinates were supposed to be captured and respond back to server for simulation). We just did some experimentations on notepad and later bailed out because of image encoding from raw graphics to optimal format + latency issues that we could not tackle at the time.
@equalsraf thanks, just tested and it worked nicely :)
@rprichard I noticed that winpty works like a unix terminal program on "raw mode"(with little/no interpretation of bytes by the terminal driver). For example:
- newline characters are not interpreted as carriage return, which is the default behavior on UNIX
-
\x03
(ETX) is not interpreted as ctrl+c -
\x04
(EOT) is not interpreted as ctrl+d
There might be others from this table that are not being handled(didnt test much). As a consequence, some keys like ctrl+c/ctrl+d still don't work(enter works because libvterm sends \r). To ensure it was not a problem on our end, I used the jobsend()
function to put these sequences directly in winpty pipe.
Also tested how winpty handles large bursts of output and was very impressed: Even though winpty gathers data through polling, it is very unlikely to miss output. To test I spawned the python interactive interpreter and did the following:
-
for i in range(10000): print(i)
: no output lost after a few tries -
for i in range(100000): print(i)
: missed a couple thousand lines in the first execution. After the first one it didn't miss any, though I was running the tests in a virtual machine and nvim had the scrollback buffer full(100k), so it was spending some CPU cleaning up the old 100k lines, which could have helped winpty polls. This might be more visible in a faster system.
Nevertheless, I don't think this will ever be an issue in real world usage, it still worked much better than I thought it would. You did an amazing work on this project, thanks again!
@rprichard I noticed that winpty works like a unix terminal program on "raw mode"(with little/no interpretation of bytes by the terminal driver). For example:
I think that roughly describes winpty's behavior. It converts input data into INPUT_RECORD
records, and line editing is all handled either by Windows itself or (sometimes) by the console application. If Windows is handling the line editing, then e.g. pressing F7 will bring up the history popup window.
- newline characters are not interpreted as carriage return, which is the default behavior on UNIX
\x03
(ETX) is not interpreted as ctrl+c
Ctrl-C is handled specially. If ENABLE_PROCESSED_INPUT
is enabled, then Ctrl-C results in a call to GenerateConsoleCtrlEvent
\x04
(EOT) is not interpreted as ctrl+dThere might be others from this table that are not being handled(didnt test much). As a consequence, some keys like ctrl+c/ctrl+d still don't work(enter works because libvterm sends \r). To ensure it was not a problem on our end, I used the
jobsend()
function to put these sequences directly in winpty pipe.
The Ctrl-modified characters are handled in the same code path as ordinary characters. winpty is delegating all the work to VkKeyScan
. In my experience, Ctrl-C and Ctrl-D have worked, so I'm not sure what issue you're hitting. (I just tested neovim-qt, and Ctrl-D seemed to work. There were other keys that didn't, like the function keys.) That same code path also handles '\x0A'/LF and '\x0D'/CR, but I'm not sure what's supposed to happen.
There is a different code path for backspace, which is handled by the "input map", which also handles all the keyboard escape sequences. The keyboard escape sequences are all listed in the DefaultInputMap.
Some tools for debugging keyboard handling:
- Set the
WINPTY_DEBUG
environment variable totrace,input
Thedump_input_map
debug flag might also be useful, but probably not. (Runwinpty-debugserver.exe
to collect the trace output.) -
winpty-agent.exe --show-input
dumps the Windows console input queue. e.g. usingReadConsoleInput
. It places the console into non-processed mode. -
console.exe --showkey
does basically the same thing asshowkey -a
on Ubuntu. IIRC, it puts the terminal into raw mode, which is what winpty is expecting as input.
Perhaps Ctrl-C is being mishandled, though, when the console is in unprocessed mode. In a normal console, --show-input
for Ctrl-C is no different than Ctrl-A:
C:\rprichard\proj\winpty\winpty>build\winpty-agent.exe --show-input
Press any keys -- Ctrl-D exits
key: dn rpt=1 scn=29 LCtrl-CONTROL ch=0
key: dn rpt=1 scn=30 LCtrl-A ch=0x1
key: up rpt=1 scn=30 LCtrl-A ch=0x1
key: up rpt=1 scn=29 CONTROL ch=0
key: dn rpt=1 scn=29 LCtrl-CONTROL ch=0
key: dn rpt=1 scn=46 LCtrl-C ch=0x3
key: up rpt=1 scn=46 LCtrl-C ch=0x3
key: up rpt=1 scn=29 CONTROL ch=0
When using winpty, though, it's converted to VK_CANCEL
:
$ build/console build/winpty-agent.exe --show-input
Press any keys -- Ctrl-D exits
key: dn rpt=1 scn=29 LCtrl-CONTROL ch=0
key: dn rpt=1 scn=30 LCtrl-A ch=0x1
key: up rpt=1 scn=30 LCtrl-A ch=0x1
key: up rpt=1 scn=29 CONTROL ch=0
key: dn rpt=1 scn=70 CANCEL ch=0x3
key: up rpt=1 scn=70 CANCEL ch=0x3
winpty doesn't implement "backpressure", though I think it should.
Whenever a user is selecting text in a Windows console, ordinary writes to the console (e.g. WriteConsole
/ WriteFile
) block, but low-level I/O can still occur (e.g. WriteConsoleOutput
, ReadConsoleOutput
). winpty exploits this behavior to prevent the console from scrolling while it's scraping the content. In theory, it could leave the console selection active if the winpty client isn't reading from the CONOUT pipe fast enough. I've been thinking about implementing this behavior for a while, but haven't gotten around to it.
Instead, IIRC, winpty has a dynamically-resizing output buffer, and if the winpty client doesn't read quickly enough, the buffer will grow arbitrarily large. That's unfortunate, because if a program is spewing output too quickly, and the user hits Ctrl-C to kill the program, output may continue spewing for a while.
FWIW: the libwinpty-rewrite
and neovim-demo
branches in winpty are obsolete now. The master
branch has a new API now that's almost identical to the one neovim used, so it should be easy to move over.
Looking at the msys2 releases, it seems the winpty.dll does not depend on msys-2.dll (which makes sense, since thats exactly what neovim needs for native builds). It might make sense to point that out in the release notes, or add another zip with just the lib and includes.
@rprichard I didn't get a chance to work this through in Neovim yet. But ideally I'd like to start a PR in https://github.com/Alexpux/MINGW-packages to have a libwinpty package.
Yes, the winpty.dll
, winpty.lib
, and winpty-agent.exe
files should be functionally equivalent across all of the packages, except for the 32-vs-64-bit difference. The code size varies quite a bit, and I think at least one package is using SJLJ exceptions.
I also wrote a ship/make_msvc_package.py
script that builds a ZIP file containing winpty.dll
, winpty.lib
, and the header files, etc. I'm currently planning to use it for the upcoming 0.4 release. It produces ZIP files like this:
Path = winpty-0.4.0-msvc2015.zip
Type = zip
Physical Size = 2368213
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2016-06-14 05:18:55 D.... 0 0 ia32
2016-06-14 05:18:55 D.... 0 0 ia32\bin
2016-06-14 05:18:55 ....A 592384 205937 ia32\bin\winpty-agent.exe
2016-06-14 05:18:55 ....A 473600 159457 ia32\bin\winpty-debugserver.exe
2016-06-14 05:18:55 ....A 509440 171321 ia32\bin\winpty.dll
2016-06-14 05:18:55 D.... 0 0 ia32\lib
2016-06-14 05:18:55 ....A 5564 1081 ia32\lib\winpty.lib
2016-06-14 05:17:57 D.... 0 0 ia32_xp
2016-06-14 05:17:57 D.... 0 0 ia32_xp\bin
2016-06-14 05:17:57 ....A 592384 205937 ia32_xp\bin\winpty-agent.exe
2016-06-14 05:17:57 ....A 473600 159455 ia32_xp\bin\winpty-debugserver.exe
2016-06-14 05:17:57 ....A 509440 171320 ia32_xp\bin\winpty.dll
2016-06-14 05:17:57 D.... 0 0 ia32_xp\lib
2016-06-14 05:17:57 ....A 5564 1080 ia32_xp\lib\winpty.lib
2016-06-14 05:19:24 D.... 0 0 include
2016-06-14 05:19:24 ....A 8885 3134 include\winpty.h
2016-06-14 05:19:24 ....A 5697 2297 include\winpty_constants.h
2016-06-14 05:19:24 ....A 1085 638 LICENSE
2016-06-14 05:19:24 ....A 5551 2324 README.md
2016-06-14 05:19:24 ....A 9783 3986 RELEASES.md
2016-06-14 05:19:24 D.... 0 0 x64
2016-06-14 05:19:24 D.... 0 0 x64\bin
2016-06-14 05:19:24 ....A 740864 244336 x64\bin\winpty-agent.exe
2016-06-14 05:19:24 ....A 592384 188421 x64\bin\winpty-debugserver.exe
2016-06-14 05:19:24 ....A 638464 203802 x64\bin\winpty.dll
2016-06-14 05:19:24 D.... 0 0 x64\lib
2016-06-14 05:19:24 ....A 5482 1077 x64\lib\winpty.lib
2016-06-14 05:18:26 D.... 0 0 x64_xp
2016-06-14 05:18:26 D.... 0 0 x64_xp\bin
2016-06-14 05:18:26 ....A 740864 244336 x64_xp\bin\winpty-agent.exe
2016-06-14 05:18:26 ....A 592384 188421 x64_xp\bin\winpty-debugserver.exe
2016-06-14 05:18:26 ....A 638464 203800 x64_xp\bin\winpty.dll
2016-06-14 05:18:26 D.... 0 0 x64_xp\lib
2016-06-14 05:18:26 ....A 5482 1077 x64_xp\lib\winpty.lib
------------------- ----- ------------ ------------ ------------------------
2016-06-14 05:19:24 7147365 2363237 21 files, 13 folders
Would that useful for neovim?
Would that useful for neovim?
Very. In fact this is very similar to the structure I had in place to fetch a prebuilt zip for winpty.