m (Execute python from within current file moved to Execute Python from within current file: Page moved by JohnBot to improve title) |
(Change to TipImported template + severe manual clean) |
||
Line 1: | Line 1: | ||
{{review}} |
{{review}} |
||
+ | {{TipImported |
||
− | {{Tip |
||
|id=609 |
|id=609 |
||
+ | |previous=608 |
||
− | |title=Execute python from within current file |
||
+ | |next=610 |
||
− | |created=November 28, 2003 |
+ | |created=November 28, 2003 |
|complexity=intermediate |
|complexity=intermediate |
||
|author=Steve Halpin |
|author=Steve Halpin |
||
|version=6.0 |
|version=6.0 |
||
|rating=14/8 |
|rating=14/8 |
||
⚫ | |||
− | |text= |
||
− | Inspired by [[VimTip608]]. |
+ | Inspired by [[VimTip608]]. |
− | To execute |
+ | To execute Python from a range within the current text file and write the output to that file (replacing the Python), add the snippet below to .vimrc (or other suitable *rc file). |
− | Requires a 'proper' |
+ | Requires a 'proper' Python setup so that the imported modules can be found. |
− | I find it a handy intermediate step between using the |
+ | I find it a handy intermediate step between using the Python interpreter on command line and running a complete script. Can be used for easy buffer manipulation, filtering input, preprocessing text and templating-like tasks. |
<pre> |
<pre> |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | + | sys.stdout = redirected |
|
⚫ | |||
− | output = redirected.getvalue().split('\n') |
||
⚫ | |||
⚫ | |||
− | + | output = redirected.getvalue().split('\n') |
|
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
</pre> |
</pre> |
||
− | ==Some examples of use |
+ | ==Some examples of use== |
===Simple=== |
===Simple=== |
||
+ | <pre> |
||
− | + | print 2 + 2 |
|
+ | </pre> |
||
+ | <pre> |
||
− | + | :Pyer |
|
+ | </pre> |
||
− | + | With the cursor on the 'print' line, that line is replaced with 4. |
|
− | ===Filter |
+ | ===Filter=== |
<pre> |
<pre> |
||
− | for line in vim.current.buffer: |
+ | for line in vim.current.buffer: |
− | if line[0] != '\t': |
+ | if line[0] != '\t': |
− | + | print line |
|
</pre> |
</pre> |
||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
<pre> |
<pre> |
||
⚫ | |||
− | import time |
||
⚫ | |||
</pre> |
</pre> |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
<pre> |
<pre> |
||
− | import |
+ | import time |
⚫ | |||
⚫ | |||
⚫ | |||
</pre> |
</pre> |
||
⚫ | |||
+ | <pre> |
||
⚫ | |||
⚫ | |||
+ | </pre> |
||
⚫ | |||
⚫ | |||
+ | <pre> |
||
+ | import urllib2,htmllib,formatter |
||
⚫ | |||
⚫ | |||
+ | </pre> |
||
− | I also use a slightly modified version that appends the output, leaving the python intact. |
||
⚫ | |||
− | |||
⚫ | |||
− | The Tipp is cool, but it does not wor the way you posted it. On my fedora core 1 I had to change it into: |
||
<pre> |
<pre> |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | def PyExecReplace(line1,line2): |
||
− | r = vim.current.buffer.range(int(line1),int(line2)) |
||
− | redirected = StringIO.StringIO() |
||
− | sys.stdout = redirected |
||
− | exec('\n'.join(r[:]) + '\n') |
||
− | sys.stdout = sys.__stdout__ |
||
− | output = redirected.getvalue().split('\n') |
||
− | r[:] = output[:-1] # the -1 is to remove the final blank line |
||
⚫ | |||
− | EOL |
||
− | command -range Pyer python PyExecReplace(<f-line1>,<f-line2>) |
||
</pre> |
</pre> |
||
− | André |
||
⚫ | |||
− | fs111--AT--linuxmail.org |
||
− | , December 1, 2003 5:23 |
||
− | ---- |
||
− | My apologies - cut & paste error, thanks for the correction. |
||
⚫ | |||
− | Now what was that vim command that takes what you actually copied to the clipboard and replaces it with what you meant to copy .... :) |
||
⚫ | |||
− | |||
− | Steve Halpin |
||
− | , December 10, 2003 10:06 |
||
− | ---- |
||
− | Hello |
||
− | |||
− | can somebody tell how to change the scrip so that it: |
||
− | # writes the python output to a new window and not replaceing the source |
||
− | # evaluates the hole buffer and not a selection |
||
− | |||
− | thank you |
||
− | |||
− | Michael |
||
− | |||
− | MIBSchmidt--AT--gmx.de |
||
− | , December 12, 2003 5:00 |
||
− | ---- |
||
− | <blockquote>>can somebody tell how to change the scrip so that it: <br/> |
||
− | >1. writes the python output to a new window and not replaceing the source </blockquote> |
||
− | ::You can just enter 'u' in command mode to 'undo' the output and get your source back. However, as you suggest sending the output to (for instance, the Preview window) would probably be better. |
||
− | |||
− | <blockquote>> 2. evaluates the hole buffer and not a selection </blockquote> |
||
− | ::':%Pyer' does this. '%' represents the whole buffer in vim. |
||
− | |||
− | |||
− | '''Anonymous''' |
||
− | , February 10, 2004 19:17 |
||
− | ---- |
||
⚫ | |||
<pre> |
<pre> |
||
− | "in ~/.vimrc: |
+ | "in ~/.vimrc: |
− | "python extensions |
+ | "python extensions |
− | py from vim import buffers, windows, command, current, error |
+ | py from vim import buffers, windows, command, current, error |
− | py import vim, sys |
+ | py import vim, sys |
− | py from vimpy import * |
+ | py from vimpy import * |
− | command! PyExecBuffer py exec('\n'.join(current.buffer)) |
+ | command! PyExecBuffer py exec('\n'.join(current.buffer)) |
− | map <F5> :PyExecBuffer<CR> |
+ | map <F5> :PyExecBuffer<CR> |
− | imap <F5> <Esc><F5><CR>a |
+ | imap <F5> <Esc><F5><CR>a |
</pre> |
</pre> |
||
vimpy.py |
vimpy.py |
||
<pre> |
<pre> |
||
− | import sys, vim |
+ | import sys, vim |
− | class Buffer: |
+ | class Buffer: |
− | def __init__(self,buf): |
+ | def __init__(self,buf): |
− | self.buf=buf |
+ | self.buf=buf |
− | def write(self,s): |
+ | def write(self,s): |
− | ll=s.split('\n') |
+ | ll=s.split('\n') |
− | self.buf[-1]+=ll[0] |
+ | self.buf[-1]+=ll[0] |
− | for l in ll[1:]: |
+ | for l in ll[1:]: |
− | self.buf.append(l) |
+ | self.buf.append(l) |
− | def clear(self): |
+ | def clear(self): |
− | del self.buf[:] |
+ | del self.buf[:] |
− | def redirect(buf=None): |
+ | def redirect(buf=None): |
− | buf = buf or vim.current.window.buffer |
+ | buf = buf or vim.current.window.buffer |
− | try: |
+ | try: |
− | sys._stdout |
+ | sys._stdout |
− | except: |
+ | except: |
− | sys._stdout=sys.stdout |
+ | sys._stdout=sys.stdout |
− | sys.stdout = Buffer(buf) |
+ | sys.stdout = Buffer(buf) |
</pre> |
</pre> |
||
− | Then |
+ | Then I start Vim, create new window (<C-W> N), and do |
− | :py redirect(current.window.buffer) |
+ | :py redirect(current.window.buffer) |
− | on a window |
+ | on a window I want to receive all printed data. |
− | Then <F5> in any buffer |
+ | Then <F5> in any buffer executes the buffer contents in Python, output goes to the window selected. |
− | To redirect output back just do sys.stdout = sys._stdout |
+ | To redirect output back just do <tt>sys.stdout = sys._stdout</tt> |
− | |||
− | tws5--AT--mail.ru |
||
− | , April 29, 2004 5:01 |
||
---- |
---- |
||
− | can any one tell me how can I use a python bot online. |
||
− | |||
− | asadhasan--AT--pakistani.com |
||
− | , May 29, 2004 12:03 |
||
− | ---- |
||
− | <!-- parsed by vimtips.py in 0.556592 seconds--> |
||
− | |||
[[Category:Python]] |
[[Category:Python]] |
Revision as of 09:40, 9 November 2007
created November 28, 2003 · complexity intermediate · author Steve Halpin · version 6.0
Inspired by VimTip608.
To execute Python from a range within the current text file and write the output to that file (replacing the Python), add the snippet below to .vimrc (or other suitable *rc file).
Requires a 'proper' Python setup so that the imported modules can be found.
I find it a handy intermediate step between using the Python interpreter on command line and running a complete script. Can be used for easy buffer manipulation, filtering input, preprocessing text and templating-like tasks.
python << EOL import vim, StringIO,sys def PyExecReplace(line1,line2): r = vim.current.buffer.range(int(line1),int(line2)) redirected = StringIO.StringIO() sys.stdout = redirected exec('\n'.join(r[:]) + '\n') sys.stdout = sys.__stdout__ output = redirected.getvalue().split('\n') r[:] = output[:-1] # the -1 is to remove the final blank line redirected.close() EOL command -range Pyer python PyExecReplace(<f-line1>,<f-line2>)
Some examples of use
Simple
print 2 + 2
:Pyer
With the cursor on the 'print' line, that line is replaced with 4.
Filter
for line in vim.current.buffer: if line[0] != '\t': print line
:%Pyer
Filters out lines beginning with a tab in the current buffer.
Inserting time
import time print time.ctime()
:%Pyer
Replaces line with date/time.
Getting web content without tags
import urllib2,htmllib,formatter h = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter())) h.feed(urllib2.urlopen('http://www.somesite.com').read())
:%Pyer
Inserts the web page text, but not the html tags, for a given site.
Comments
I use the following:
"in ~/.vimrc: "python extensions py from vim import buffers, windows, command, current, error py import vim, sys py from vimpy import * command! PyExecBuffer py exec('\n'.join(current.buffer)) map <F5> :PyExecBuffer<CR> imap <F5> <Esc><F5><CR>a
vimpy.py
import sys, vim class Buffer: def __init__(self,buf): self.buf=buf def write(self,s): ll=s.split('\n') self.buf[-1]+=ll[0] for l in ll[1:]: self.buf.append(l) def clear(self): del self.buf[:] def redirect(buf=None): buf = buf or vim.current.window.buffer try: sys._stdout except: sys._stdout=sys.stdout sys.stdout = Buffer(buf)
Then I start Vim, create new window (<C-W> N), and do
:py redirect(current.window.buffer)
on a window I want to receive all printed data.
Then <F5> in any buffer executes the buffer contents in Python, output goes to the window selected.
To redirect output back just do sys.stdout = sys._stdout