3

I get a human readable list of api functions using

:new|put =map(api_info().functions, 'v:val.name')

in neovim as suggested on https://neovim.io/doc/user/msgpack_rpc.html.

Problem is, this doesn't show the method signatures like the perl example on http://techblog.babyl.ca/entry/neovim-way-to-go.

#!/usr/bin/env perl 
use Neovim::RPC;
my $rpc = Neovim::RPC->new->api->print_command;

yielding

...
vim_replace_termcodes ( String str, Boolean from_part, Boolean do_lt, Boolean special ) -> String
...
vim_set_current_line ( String line ) -> void
...

But: I don't use perl, I want to use python and want to print a formatted dump of the neovim api as suggested in https://neovim.io/doc/user/msgpack_rpc.html.

nvim --api-info | python -c 'import msgpack, sys, yaml; print( yaml.dump(msgpack.unpackb(sys.stdin.read())) )'

However, I get the following error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/info/w/sc/lib/python3.4/codecs.py", line 319, in decode
     (result, consumed) = self._buffer_decode(data, self.errors, final)
 UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 0: invalid start byte

Trying to isolate the error, I did

nvim --api-info | python -c 'import sys; print( sys.stdin.read() )'

resulting in the same error as above.

I think the reason is me using python 3.4 not python 2.7. How do you correctly code this in python 3.4?

Moreover, there seems to be a discrepancy between the api function and the python implementation, e.g. if you want to access the api function vim_set_current_line, you need to write

from neovim import attach
v = attach('socket', path='/tmp/nvim')
v.api.set_current_line("zzzz")

and not v.api.vim_set_current_line("zzzz").

Is there a way to find out about "pythonic" api-functions (apart from consulting https://github.com/neovim/python-client/tree/master/neovim/api) ?

3
  • This looks like an encoding error, rather than a python version error. What happens if you try yaml.safe_dump in place of yaml.dump? (Disclaimer, I no absolutely nothing about yaml)
    – DJMcMayhem
    Commented Jun 27, 2016 at 19:59
  • It results in the same error. I tried to isolate the error (see editing above). It seems you are right and it is an encoding error, but has nothing to do with yaml.
    – Markus
    Commented Jun 27, 2016 at 20:10
  • Closest to the solution of my first question seems to be nvim --api-info | python -c 'import msgpack, sys; print( msgpack.unpackb(sys.stdin.buffer.read()) )', but it is not formatted yet.
    – Markus
    Commented Jun 27, 2016 at 20:19

2 Answers 2

3

In Python 3, there's an emphasis on unicode strings. sys.stdin has a buffer attribute that lets you get to the underlying byte buffer, but Python 2's sys.stdin does not. If you want something that'll work for both versions, you can use the -u command line argument, as well as getattr():

nvim --api-info | python -u -c 'import sys,msgpack; print(msgpack.unpackb(getattr(sys.stdin, "buffer", sys.stdin).read()))'

The relevant bit is:

getattr(sys.stdin, "buffer", sys.stdin).read()

If you're more comfortable using Neovim to work with the text, there is also the api_info() function in Neovim.

3
  • 2
    The api_info() function is, as of 2016/06/27, unreleased. If you're building from git you'll be able to use it. It will be in the 0.1.5 release.
    – jamessan
    Commented Jun 27, 2016 at 20:24
  • typing :echo api_info() in neovim yields a dictionary with myriads of characters, but unformatted. The short-hand version of Tommy A, namely nvim --api-info | python -c 'import msgpack, sys; print( msgpack.unpackb(sys.stdin.buffer.read()) )', has the same result, this time in unformatted python bytecode. nvim --api-info | python -c 'import msgpack, sys, yaml; print( yaml.dump(msgpack.unpackb(sys.stdin.buffer.read())) )' is perfectly formatted, but unreadable, as it seems to be some different codec (base64???)
    – Markus
    Commented Jun 27, 2016 at 20:38
  • 1
    @Markus The point was to get the information out of the binary format. It's up to you if you want to format it with json or yaml. The base64 encoded text is because msgpack created raw bytes and pyaml is treating it as binary data. Pass encoding="utf8" to the msgpack.unpackb() function if you want it to create unicode strings.
    – Tommy A
    Commented Jun 27, 2016 at 20:53
-1

For python 3 use this:

nvim --api-info | python -c 'import msgpack, sys, yaml; print( yaml.dump(msgpack.unpackb(sys.stdin.buffer.read(), raw=False)))' | less
2
  • 1
    Welcome on the site! How does it work?
    – peterh
    Commented Jul 7, 2019 at 8:25
  • 2
    Welcome to this site! Your answer has been flagged as low quality because of its length. On this site we encourage user to detail their answer so that reader don't simply copy and paste chunks of code but actually understand what they do. For example as your answer is pretty close from the accepted one it would be useful to point out the differences and explain why one would prefer using your version rather than the other one.
    – statox
    Commented Jul 8, 2019 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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