I have been using vim for coding in C and am currently switching to it for python as well.
I have the following line in my vimrc
autocmd FileType python map <buffer> <leader><ENTER> :w<CR>:exec '!python3' shellescape(#%, 1)<CR>
As my python files get more and more complicated, the time for processing the entire file takes longer as well. I was wondering if there is a way to keep my previous variables in memory and only run the additional lines of commands, just as I would in an interactive python session. Sending the full file to bash runs the entire script and clears all the memory.
text = read_file('my_file.txt')
text_index = index(text)
pattern = 'asdjhlsajf'
def search:
...
Basically, is there a way to send these commands line by line to an interactive python session from vim?
As #Doktor OSwaldo, #filbranden, amd #shaahiin suggested, vim-slime was a great choice (vim-ipython-cell has some additional scripts).
I downloaded the plugin using:
mkdir -p ~/.vim/pack/plugins/start
cd ~/.vim/pack/plugins/start
git clone https://github.com/jpalardy/vim-slime.git
Added the following to ~/.vimrc:
let g:slime_target = "tmux"
let g:slime_python_ipython = 1
filetype plugin on
Then used two tmux windows. One for vim, and the other for the iPython. using
cntrl-c + cntrl-c
commands could be send to the iPython session.
Related
I'm trying a simple way to compile pdfs in LaTeX and open them with zathura from a single autocmd inside vim, so far I tried:
command Latex !pdflatex %:t
command Za !zathura #%.pdf
autocmd FileType tex map <leader>pdf :w<CR>:Latex<CR>:Za <CR>
Obviously, #%.pdf is wrong, but I've had no luck in finding how to append an extension to the file name. I'm newbie in vim scripting so please point out any other errors.
Since no one bother to answer, I came up with a shell solution for it, a script called zatex:
tex=".tex"
pdf=".pdf"
cd $1;
texfile="$2$tex";
pdflatex $texfile;
pdffile="$2$pdf";
setsid zathura $pdffile;
And inside my .vimrc:
command Zatex !zatex %:p:h %:p:h:t
autocmd FileType tex map <leader>pdf :w<CR>:Zatex<CR>
Of course, after the first compiling it might be handy to have another mapping just to compile the pdf, since zathura is already open:
command Latex !pdflatex %:t
autocmd FileType tex map <leader>tex :w<CR>:Latex<CR>
I believe %:r is what you are looking for, without the # character. It will return the file name, without extension.
Also, have a look at this question.
EDIT: I just tested here (not with !zathura, but with !echo) and the following line should work for you (just append the correct extension after the file name expand):
command Za !zathura %:r.pdf
In my init.vim for Neovim, I have the same line as in my .vimrc in Vim, which, when pressing F12, runs the file currently in the buffer using the python3 interpreter:
autocmd FileType python nnoremap <silent> <F12> :!clear;python3 %<CR>
Now I'm trying to run this tiny "test.py" script by pressing F12 in normal mode:
import IPython
IPython.embed()
Works fine in Vim:
But doesn't work in neovim despite exactly the same line in my ~/config/nvim/init.vim:
So it does run IPython, but then immediately (red arrow) inexplicably asks if I want to exit. It's also got a bunch of weird escape sequences inserted (yellow arrow) which I suspect are the reason why it wants to exit, and which don't appear with normal vim.
I don't really like the internal neovim terminal, so how can I get neovim to behave exactly like vim in this case?
This is a known limitation of NeoVim, :! is non-interactive and it will not allocate a pseudo-terminal which is typically required for full-screen applications such as IPython to run properly.
See issue #1496 for details.
An alternative is to use NeoVim's (or Vim 8's) support for terminal, with the :terminal command, or with a function such aa termopen() (in NeoVim) or term_start() (in Vim 8) to run full-screen applications such as IPython.
In your case, something as simple as :term python3 %, running the command in a terminal in a split, might be an adequate replacement.
You might also find the vim-bang-terminal plug-in interesting. It replaces a :! command with a similar command invocation that runs inside a Vim/NeoVim terminal instead.
I'm trying to incorporate vim into my main workflow. A major sticking point for me has been interactively editing and running programs/scripts.
For example given that I'm currently vimmed into test.py
print('hello')
x = 5
y = x+2
print(y)
Without leaving vim how would I:
a) run the whole script without leaving vim
b) run just "print('hello')"
Commenters and the other answer have pointed out how to run a file from vim. But they glossed over some really powerful possibilities. I'd like to explain how some of those work in more detail.
The simplest possible way of running a python script in vim, is to just call the python interpreter on the file, e.g.
:!python %
or, as I prefer to do to make sure there are no unsaved changes,
:w | !python %
But it is not even necessary to have a file to run a python script in vim. The reason why is because :w != save! :w means write, and if no argument is provided, it happens to write to the file you are editing. However, you can write to STDOUT, to another file, or even to another program. So if you'd like to run your buffer as python code without having a file to save and run, you may simply do:
:w !python
This meanse write the current buffer into the external program "python". This literally just sends the contents of your buffer directly to python.
Now here's where it gets really cool. In vim, :w is an "ex command", e.g. a command that you run from the vim command line that originally came from ex, a very old line based unix text editor. The awesome thing about ex commands is that since they are all line based, you can directly state which lines you would like the command to apply to. For example:
:2w myfile.txt
will write only line two to the file "myfile.txt". You can even supply a range, e.g.
:2,7w myfile.txt
will write lines 2-7 to "myfile.txt". This means that using your example, we can run
:1w !python
to run just
print('hello')
To make this more convenient, you can use visual mode to select every line you would like to run, which will automatically fill in the right range for you. This will look like
:'<,'>w !python
To make this more convenient, I would recommend adding something like
xnoremap <leader>p :w !python<cr>
to your .vimrc. Then you can visually select whatever you want and run it as python code by typing
\p
(replace \ with whatever you have set up as your leader). You could also do
nnoremap <leader>p :w !python<cr>
or
nnoremap <leader>p :w | !python %<cr>
depending on whether you want to save to a file or not.
Create a function for a range as discussed in this question:
fu PyRun() range
echo system('python -c ' . shellescape(join(getline(a:firstline, a:lastline), "\n")))
endf
Create a mapping for visual mode:
vmap <C-F6> :call PyRun()<CR>
Then you can select a range and press Control-F6. The range of lines will be executed by python. The result will be displayed in the command area.
You can run a program from vim using :!, i.e. :!python3 % to run your current script.
If you want to bind a key to it, another easy way would be to set makeprg to your python executable: :set makeprg=python3 and then bind a key to :make<cr>. In that case I would set up autocmds that switch the makeprg depending on the file type.
If you want to run a simple statement, you could either use Python's -c switch:
:!python3 -c 'print("Hello world")', or you could just run :!python3 without arguments to be dropped into a REPL without leaving Vim.
As part of learning Haskell, for fun I'm attempting to use Raspberry PI. Having encountered a myriad of issues installing ghci on the PI I've resolved to using just ghc.
So to create, compile & run a new Haskell file :
vi first.hs
i
main = putStrLn "First"
Esc
:w
:q
ghc -o first first.hs
./first
Output is : "First"
I would like to automate the commands :
Esc
:w
:q
ghc -o first first.hs
./first
Can these be added as new command from within vi / vim, something like :
:mycustomcommands
And run from within the vi / vim editor ?
Maybe you could try adding something like this to your vimrc:
function! ExecuteHS()
w
!ghc -o first %
!./first
endfunction
And to use this function you just have to call it like that :call ExecuteHS(). Vim will be put on background during the execution of your file and will then come back on foreground at the end of the execution.
As a bonus you can add the folowing line to your vimrc
nnoremap <key> :call ExecuteHS()<CR>
Replacing <key> with your prefered key combination <Leader>e for example. This way you'll simply have to hit ,e (if you didn't changed your leader key) in normal mode to call the function.
That's probably not the cleanest way to do it but it should work for what you want.
Absolutely in vim, though not necessarily in other vi flavors. See this tutorial on defining custom commands. Put the custom command in your vimrc and it will always be available as :Customcmd or whatever you call it. For one-button access, you can use :remap to assign a hotkey to your custom command or the sequence of built-in commands you want to run. This is a tutorial on keymappings that will give you more information.
I second #statox's referral to https://vi.stackexchange.com :)
I use vim-haskell, which includes a couple nice things. In particular, it includes a file for setting up cabal-install as the compiler, which is a very nice way of working. Dump this in ~/.vim/compiler/cabal-build.vim:
CompilerSet makeprg=cabal\ build
CompilerSet errorformat=
\%W%f:%l:%c:\ Warning:%m,
\%W%f:%l:%c:\ Warning:,
\%E%f:%l:%c:%m,
\%E%f:%l:%c:,
\%C\ \ %#%m,
\%-G%.%#,
\%-G%.%#
And this in ~/.vim/ftplugin/haskell.vim:
compiler cabal-build
(The argument to compiler should match the name of the file you put in ~/.vim/compiler.) Then you can run :make in vim and it will save any changed buffers (assuming autowrite is set) and build your project. When there are errors, it will populate the quick-fix list, which lets you jump to the specific file and line numbers of each error or warning with a key. Read more about this feature with :help quickfix. Once everything is working, you can :!cabal run to run it.
This is in reference to the accepted answer here written by Paul Biggar:
After considering all these options for some time, I have settled with the following solution.
Set vim to write continuously as I type.
Run a script in the background to build continuously, refreshing the pdf as it goes. latexmk is nearly good enough, except that it builds in place, which gets reloaded at a bad time in okular (my viewer).
The script is available at https://github.com/pbiggar/texbuild.
Use rubber-info to get the errors and warnings from the log file. The script above saves the log file in t.log. In vim:
autocmd FileType tex set makeprg=rubber-info\ t.log
autocmd FileType tex set errorformat=%f:%l:\ %m
I want to execute his github script in order to "build [LaTeX files] continuously, refreshing the pdf as it goes." Given that he doesn't exactly offer instructions how to run it, I assume this is a rather trivial procedure. However, I'm quite new at vim and know very little about programming/github in general, so I really have no clue how to start.
I've searched high and low, and have made zero progress. I'm not sure if the code is supposed to be compiled in python, then run as a script, or anything similar. I appreciate your help!
EDIT: As per the comments discussion, I've successfully made the script executable. But I still don't know how to run it..?
The
#!/usr/bin/env python
at the top of the script states, as well as absence of import vim in the body clearly states that it should be run from the shell (or from vim) using
chmod +x /path/to/texbuild # Needed only once
/path/to/texbuild {script-args}
. Further exploration reveals that it expects to have one tex file as its first and only argument (the only place where sys.argv is mentioned is line 48) hence it is likely that you should use the following to run it:
augroup AutorunTexbuild
autocmd!
autocmd FileType tex :if !exists('b:runtexbuild') | call system('/path/to/texbuild '.shellescape(#%)) | let b:runtexbuild=1 | endif
autocmd VimLeave * :call system('killall -TERM texbuild')
augroup END
. That assumes that you edit tex files only in one vim instance at a time. It looks like author expected you to run that script manually.