how to map F4 run a no name file on vim? - python

I add a line in _vimrc .
map <F4> :w<cr>:!python %<cr>
If the file contain name ,it can run,if the file is a new edited which contain no name ,when i press F4 ,it can't run .
I want to make my configuration more smart ,and don't want to save it ,give it a name and press F4,how can i revise map <F4> :w<cr>:!python %<cr> to make the no name python file to run ?

How about using :w !{cmd}? (This does not require you to save before run the command).
:map <F4> :w !python<cr>
According to vim help :w_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 |:!|.
NOTE This will not work as expected if the Python program itself use filename. (For example, __file__ will yield '<stdin>')

Related

File content as PyCharm run configuration parameters

I'm trying to launch may main Python script with some arguments listed in a txt file (config.txt).
Because parameters change almost every launch and I dont want to type them every time. They are not literally a "config" but I didn't find the correct file name (that's an other story).
See below:
-param1 1
-param2 2
-verbose
Using Run Configuration of PyCharm.
I would like to finally do something like :
python C:\somewhere\main.py -param1 1 -param2 2 -verbose
Instead of current behavior :python C:\somewhere\main.py config.txt
Which, by the way, is missed understood by the program (obviously).
#32951846
I already tried windows for loops in the section "before launch: activate tools":
$: for /f "delims=" %x in (config.txt) do set ARGS=%ARGS%%x
$: python C:\somewhere\main.py %ARGS%
But it only keep the last line of the config.txt inside ARGS.
#51948712
I also tried to pipe the content of the file into my python main program like:
python C:\somewhere\main.py < config.txt
But it do not work neither.
#syntax-redirection
Am I right that you'd like to see something like https://youtrack.jetbrains.com/issue/PY-5543?
Consider using the following plugin: https://plugins.jetbrains.com/plugin/7861-envfile/
This is not exactly what you were asking for, but you can follow this guideline to store the run configurations in a file and then modify the file, share it or add to git.
The key steps are to tick the box "Store as project file" in PyCharm's "Run/Debug Configurations" window. This will create the new subfolder "runConfigurations" in the ".idea" folder in the project folder.
The folder will contain an xml file with the line
<option name="PARAMETERS" value=""arg1" "arg2"" />
where "arg1" and "arg2" are the arguments which are passed to your script.

Python 3 from CMD

I am attempting to run this .PY file from Command Prompt:
# Merge two .BSG files
# Starting block and world position are taken from the first file
# Example: "bsgmerge input.bsg output.bsg merged.bsg"
import io, sys
one = open(sys.argv[1]).readlines()
two = open(sys.argv[2]).readlines()
for n in [1,3,5,7,9,11,17,19,21,23]:
one[n] = one[n][:-1]+"|"+two[n].partition("|")[2]
open(sys.argv[3],"w").write("".join(one))
It is a program that takes a creation from the game Beseige and merges it with another saved creation so that opening the merged file results in both creations being present. If you want more details, you can read up on that here.
I am having trouble figuring out how to call this program from the command line. At first I thought the problem was me having Python 2 (it requires Python 3), so I uninstalled 2 and installed 3. This did not help.
What I am doing is entering the "python" command to pull up the Python environment within CMD, then entering the command to call the program based on the third comment in the file ("bsgmerge input.bsg output.bsg merged.bsg").
I tried using full file paths or simply changing to the correct directory before typing the "python" command and using only the file names, but so far I've had no luck.
When I am in the correct directory, then enter the Python environment, typing the command "bsgmerge 1.bsg 2.bsg M.bsg" (my existing files to be merged are 1.bsg and 2.bsg), this error occurs:
File "<stdin>", line 1
bsgmerge 1.bsg 2.bsg M.bsg
^
SyntaxError: invalid syntax
I took a Python course (which is why I used to have Python 2 on my machine) last fall, so I noticed that there is no "def" defining a function in the above code, which is something I've never encountered, so I'm thinking that is the root of my problems.
Thanks in advance for the help.
I was probably same problem with python launcher.
If you use Linux, first line shoud be:
#! /path/to/your/python/3
In Windows it some more complicated:
In registry by regedit change
HKEY_CLASSES_ROOT\Python.File\shell\open\command from "C:\Python27\python.exe" "%1" %* to "C:\Windows\py.exe" "%1" %*.
And first line of script shoud be:
#! python3
Now it shoud work properly.

Why doesn't my bash script read lines from a file when called from a python script?

I am trying to write a small program in bash and part of it needs to be able to get some values from a txt file where the different files are separated by a line, and then either add each line to a variable or add each line to one array.
So far I have tried this:
FILE=$"transfer_config.csv"
while read line
do
MYARRAY[$index]="$line"
index=$(($index+1))
done < $FILE
echo ${MYARRAY[0]}
This just produces a blank line though, and not what was on the first line of the config file.
I am not returned with any errors which is why I am not too sure why this is happening.
The bash script is called though a python script using os.system("$HOME/bin/mcserver_config/server_transfer/down/createRemoteFolder"), but if I simply call it after the python program has made the file which the bash script reads, it works.
I am almost 100% sure it is not an issue with the directories, because pwd at the top of the bash script shows it in the correct directory, and the python program is also creating the data file in the correct place.
Any help is much appreciated.
EDIT:
I also tried the subprocess.call("path_to_script", shell=True) to see if it would make a difference, I know it is unlikely but it didn't.
I suspect that when calling the bash script from python, having just created the file, you are not really finished with that file: you should either explicitly close the file or use a with construct.
Otherwise, the written data is still in any buffer (from the file object, or in the OS, or wherever). Only closing (or at least flushing) the file makes sure the data is indeed in the file.
BTW, instead of os.system, you should use the subprocess module...

auto run python result in "EOF when reading a line "

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>
I think the problem is the input() line. Python is looking for input and not finding any. All it finds (wherever it looks) is an EOF.
One way to do this without a temp file, would be to do something like this(with a small helper function):
function! GetContentsForPython()
let contents = join(getline(1,'$'), "\n")
let res = ''
for l in split(contents, '\n')
if len(l)
let res = res . l . ';'
endif
endfor
let res = '"' . escape(res, '"') . '"'
return res
endfunction
noremap <f4> :!python -c <c-r>=GetContentsForPython()<cr><cr>
This gets the contents of the current buffer, and replaces the newlines with semi colons so you can execute it with
python -c "print 'hello'"
There may be better ways accomplishing this, but this seems to work for me.

Automatically inserting a header in vim

Is there a way to auto add a header when i open a new file in vim?
My objective is to automatically add the shebang "#! /usr/bin/python" when i open a new file using the command "vim test.py". If the file is already present, no header should be inserted.
Add this line in your configuration file:
autocmd BufNewFile *.py 0put =\"#!/usr/bin/python\<nl>\"|$
This might be over-kill, but you could look at one of the snippet scripts for Vim, e.g. snipMate -- http://www.vim.org/scripts/script.php?script_id=2540
But, for what you want, you might just map a key to a command that reads in a file. For example:
nmap <leader>r :r boiler_mashbang<cr>
And, then put your boilerplate in the file: boiler_mashbang.

Categories