vim 8 support terminal, and has a api to let command in terminal to communicate back to vim.

For example:

In vim, define function like

" .vimrc
let g:cnt = get(g:, 'cnt', 0)
func! Tapi_Command_finish(bufnum, arglist) abort
    let g:cnt += 1
endfunc " Tapi_Command_finish

open a terminal buffer, run command

printf '\033]51;["call","Tapi_%s", ["%s"]]\007' Command_finish

then go back to vim, :echo g:cnt, 1 will be echoed, demonstrate function Tapi_Command_finish being called.

This works in linux, but when i tried on windows gvim 8, it did not work.

I search around, some say cmd do not support ansi escape sequence. (not sure if \033]51... is ansi escape sequence or not.)

The question:

Is there a way to use terminal api on windows gvim?

== EDIT == (The echo part)

Below are 3 ways I can thought of to reproduce the echo part.

  • 1 cat file approach

under posix shell, eg, cygwin

printf '\033]51;["call","Tapi_%s", ["%s"]]\007' Command_finish > xx

and cp or scp to current directory. then in terminal buffer

type xx
  • 2 use python

create file yy.py, with content

print('\033]51;["call","Tapi_%s", ["%s"]]\007' % ("Command_finish",""))

then in terminal buffer, run

python yy.py
  • 3 use echo

not tried, since I don't know how to reliably send '\033'.

Of the 3 ways, both 1 & 2 works on cygwin.

  • Which command did you use in Windows cmd? echo? I guess that's perhaps one of the most important parts to reproducing your issue... – filbranden Feb 24 at 3:35
  • @filbranden, have edited the question to add description about echo part. – qeatzy Feb 24 at 5:16
  • Thanks! Btw, what do you mean by "works on cygwin"... Do you mean if you have a :terminal window and run Cygwin bash there? But it doesn't work if :terminal is running cmd.exe? Not even the Python one? (I'd expect it would behave similarly on Cygwin and on Windows)... Or by "on cygwin" do you mean running Vim from cygwin inside the cygwin shell, in which case the :terminal window will be a Posix shell I'd expect? – filbranden Feb 24 at 5:23
  • 1
    I mean use cygwin mintty itself, independent of gvim, just like regular unix terminal. BTW, I don't know to use other terminal under windows gvim. – qeatzy Feb 24 at 5:26
  • Thanks for the clarifications! Windows world is indeed a bit foreign to me so I don't really know the details of Windows terminal and how Vim's :terminal works there... It's a good question, hopefully you'll get a good answer for it! – filbranden Feb 24 at 5:27

So :help terminal-communication lists term_sendkeys(), then the JSON API you can access with the escape sequence, then finally:

Use the client-server mechanism. This works on machines with an X server and on MS-Windows.

I'm not sure if that's meant to say that the other mechanisms will not work on MS-Windows, but at least they're saying this one should work there.

Then :help terminal-client-server describes that in more detail. You need to have your Vim instance register a server name (which it might do automatically, but you might need to do yourself.) Then, when you open a new :terminal, the server name will be available in an environment variable, $VIM_SERVERNAME (I believe this will be the case in cmd.exe as well, though probably it will be %VIM_SERVERNAME% there.)

From there, you can call a gvim --remote command, to either open a file on that Vim server, or to actually evaluate an expression or send keystrokes to be executed.

The exame from the help page, opening a file:

vim --servername $VIM_SERVERNAME --remote +123 some_file.c

But you'll probably want to look into :help --remote-expr (and possibly --remote-send as well.)

Note that this mechanism is a lot more powerful than the JSON API, since you can use it to evaluate arbitrary expressions, call arbitrary functions, send keystrokes. It's also synchronous and bidirectional, since you can evaluate expressions and get their result from the command running on the terminal.

On the other hand, it's heavier (need to invoke the Vim binary), less portable and might require some setup (ensuring the server is running and has a server name set.)

Having said that, you might want to consider that as an option, since it seems to be perfectly suited for the environment you're on.

| improve this answer | |
  • 1
    Thx, I tried --remote-expr, which solved my problem. The caveat is needing to spawn vim to just send some message. But it works, that's enough. Thx for your help, I didn't realize vim server can be used here. Upvoted, but not accept since I leave it to terminal api approach, but it might be a long time before it being implemented. – qeatzy Feb 24 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.