I have add the line into my .vimrc
map <F4> :w !python<cr>
When I open gvim to edit an unname Python file, there are only two lines in it
x=input("which one do you like ? ")
print(x)
I press F4, and get EOF when reading a line
, how to solve it?
When you add map <F4> :w<cr>:!python %<cr>
or imap <F4> <Esc>:w <cr>:!python %<cr>
, it can only make a named file run, if it is a no named file, the map will not work, how can I make the no named file run?
@benjifisher's answer is correct. The input (function) is the problem.
The :w !python
pipes the program to python through stdin (Basically the same as
echo 'input("x")' | python
which also fails if run in the shell). However input()
tries to read from stdin which it can't do because python read the program from stdin and stdin is still trying to read from the pipe. However the pipe is already at the end and won't ever contain new data. So input()
just reads EOF.
To see that python is reading from stdin we look at :h :w_c
which shows that the file is being passed to stdin of the cmd which in this case is python.
:w_c :write_c
:[range]w[rite] [++opt] !{cmd}
Execute {cmd} with [range] lines as standard input
(note the space in front of the '!'). {cmd} is
executed like with ":!{cmd}", any '!' is replaced with
the previous command :!.
If the buffer had contained something that wasn't reading from stdin your mapping would have worked.
For example if the unnamed buffer contains
print(42)
running the command :w !python
in vim prints 42.
So the problem isn't that the mapping fails. The problem is that your program doesn't know how to get input. The solution is use either a named file or don't write interactive programs in vim. Use the python interpreter for that.
Since you have :w
in your mapping, I am assuming you either want to run the script directly from the insert mode or you want to save it anyways before running it.
Multiple commands in vim require a separator like <bar>
i.e. (|
) or use <CR>
(Carriage Return) between and after commands.
You can put both of the mappings below in your .vimrc
and they should meet your requirement on hitting F4
, whether you are in normal mode or insert mode.
If you are in normal mode, you are fine with map
:
map <F4> :w<cr>:!python %<cr>
While for insert mode, you would need imap
and an Esc
to get out of insert mode:
imap <F4> <Esc>:w <cr>:!python %<cr>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With