How do I get the value returned from a function in

2020-04-10 18:47发布

I'm using Python to write a vim plugin, but there's something wrong when dealing with Vimscript.

function! Login()  
python << EOF    
import vim, weibo
appkey = 'xxx'
appsecret = 'xxxxx'
callback_url = 'xxxxxxxx'
acs_token = 'xxxxx'
expr_in = 'xxxx'
client = weibo.APIClient(app_key=appkey, app_secret=appsecret,\
         redirect_uri=callback_url)
client.set_access_token(acs_token, expr_in)
del vim.current.buffer[:]  
EOF    
return client
endfunction


function! Post()  
python << EOF
import vim, weibo
try: 
    vim.command("let client = Login()")  # line1
    client.post.statuses__update(status="hello") # line2
except Exception, e:
    print e
EOF
endfunction

Here, there're always errors like "Undefined variable" and "Invalid expression" when I call Post(), but line2 always succeeds executing.

I've not learned Vimscript before, could anybody tell me what I should do to avoid those errors?

1条回答
放荡不羁爱自由
2楼-- · 2020-04-10 19:14

Since you have now added your whole function...

The reason you get an undefined variable and Invalid expression in Login() is because the scope of client ends at EOF. At the return line vim does not know about client because it is only defined within the python block.

What you could do is just define a python function that does this for you inside Post(). Something like the following.

python << EOF
import vim, weibo
def Login():
    appkey = 'xxx'
    appsecret = 'xxxxx'
    callback_url = 'xxxxxxxx'
    acs_token = 'xxxxx'
    expr_in = 'xxxx'
    client = weibo.APIClient(app_key=appkey, app_secret=appsecret,\
             redirect_uri=callback_url)
    client.set_access_token(acs_token, expr_in)
    del vim.current.buffer[:]  
    return client
EOF

function! Post()  
python << EOF
try: 
    client = Login()
    client.post.statuses__update(status="hello")
except Exception, e:
    print e
EOF
endfunction

NOTE: Since everything is passed to the same instance of python you can just define Login() as a normal python function outside of the vim function and do what ever you want later. It does not need to be in the same python block.


Old Answer

You need to put the symbol EOF at the end of your python sections. Otherwise vim keeps feeding the commands to python.

python << EOF

The appropriate section from the vim help :h python-commands is copied below.

:[range]py[thon] << {endmarker}
{script}
{endmarker}
            Execute Python script {script}.

{endmarker} must NOT be preceded by any white space.  If {endmarker} is
omitted from after the "<<", a dot '.' must be used after {script}, like
for the |:append| and |:insert| commands.
This form of the |:python| command is mainly useful for including python code
in Vim scripts.

Your {endmarker} is EOF. However since you do not show the whole function I am not sure where you need to put EOF


As for your code.

vim.command("let obj = Login()")

This line is correct. If and only if Login() executes without error. However with the snippet you show Login has errors.

查看更多
登录 后发表回答