1
"""Shell mode for IPython.
3
Start ipython in shell mode by invoking "ipython -p sh"
5
(the old version, "ipython -p pysh" still works but this is the more "modern"
6
shell mode and is recommended for users who don't care about pysh-mode
10
from IPython import ipapi
13
# The import below effectively obsoletes your old-style ipythonrc[.ini],
14
# so consider yourself warned!
21
# autocall to "full" mode (smart mode is default, I like full mode)
25
# Jason Orendorff's path class is handy to have in user namespace
26
# if you are doing shell-like stuff
28
ip.ex("from IPython.external.path import path" )
32
# beefed up %env is handy in shell mode
35
# To see where mycmd resides (in path/aliases), do %which mycmd
38
# tab completers for hg, svn, ...
39
import ipy_app_completers
41
# To make executables foo and bar in mybin usable without PATH change, do:
49
ip.ex("def up(): os.chdir('..')")
53
o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
54
o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
57
from IPython import Release
61
o.banner = "IPython %s [on Py %s]\n" % (Release.version,sys.version.split(None,1)[0])
64
ip.IP.default_option('cd','-q')
65
ip.IP.default_option('macro', '-r')
66
# If you only rarely want to execute the things you %edit...
67
#ip.IP.default_option('edit','-x')
70
o.prompts_pad_left="1"
71
# Remove all blank lines in between prompts, like a normal shell.
76
# now alias all syscommands
80
syscmds = db.get("syscmdlist",[] )
82
print textwrap.dedent("""
83
System command list not initialized, probably the first run...
84
running %rehashx to refresh the command list. Run %rehashx
85
again to refresh command list (after installing new software etc.)
88
syscmds = db.get("syscmdlist")
90
# lowcase aliases on win32 only
91
if os.name == 'posix':
94
def mapper(s): return s.lower()
97
# print "sys",cmd #dbg
98
noext, ext = os.path.splitext(cmd)
100
if key not in ip.IP.alias_table:
101
ip.defalias(key, cmd)
103
# mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
104
ip.load("IPython.external.mglob")
106
# win32 is crippled w/o cygwin, try to help it a little bit
107
if sys.platform == 'win32':
108
if 'cygwin' in os.environ['PATH'].lower():
109
# use the colors of cygwin ls (recommended)
110
ip.defalias('d', 'ls -F --color=auto')
112
# get icp, imv, imkdir, igrep, irm,...
115
# and the next best thing to real 'ls -F'
116
ip.defalias('d','dir /w /og /on')
118
extend_shell_behavior(ip)
120
# XXX You do not need to understand the next function!
121
# This should probably be moved out of profile
123
def extend_shell_behavior(ip):
125
# Instead of making signature a global variable tie it to IPSHELL.
126
# In future if it is required to distinguish between different
127
# shells we can assign a signature per shell basis
128
ip.IP.__sig__ = 0xa005
129
# mark the IPSHELL with this signature
130
ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
132
from IPython.Itpl import ItplNS
133
from IPython.genutils import shell
134
# utility to expand user variables via Itpl
135
# xxx do something sensible with depth?
136
ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
137
str(ItplNS(cmd, ip.IP.user_ns, get_locals()))
140
""" Substituting a variable through Itpl deep inside the IPSHELL stack
141
requires the knowledge of all the variables in scope upto the last
142
IPSHELL frame. This routine simply merges all the local variables
143
on the IPSHELL stack without worrying about their scope rules
146
# note lambda expression constitues a function call
147
# hence fno should be incremented by one
148
getsig = lambda fno: sys._getframe(fno+1).f_globals \
149
['__builtins__'].__dict__['__sig__']
150
getlvars = lambda fno: sys._getframe(fno+1).f_locals
151
# trackback until we enter the IPSHELL
157
fsig = getsig(frame_no)
158
except (AttributeError, KeyError):
162
# call did not originate from IPSHELL
164
first_frame = frame_no
165
# walk further back until we exit from IPSHELL or deplete stack
167
while(sig == getsig(frame_no+1)):
169
except (AttributeError, KeyError, ValueError):
171
# merge the locals from top down hence overriding
172
# any re-definitions of variables, functions etc.
174
for fno in range(frame_no, first_frame-1, -1):
175
lvars.update(getlvars(fno))
176
#print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
179
def _runlines(lines):
180
"""Run a string of one or more lines of source.
182
This method is capable of running a string containing multiple source
183
lines, as if they had been entered at the IPython prompt. Since it
184
exposes IPython's processing machinery, the given strings can contain
185
magic calls (%magic), special shell access (!cmd), etc."""
187
# We must start with a clean buffer, in case this is run from an
188
# interactive IPython session (via a magic, for example).
190
lines = lines.split('\n')
194
# skip blank lines so we don't mess up the prompt counter, but do
195
# NOT skip even a blank line if we are in a code block (more is
197
# if command is not empty trim the line
200
# add the broken line to the command
201
if line and line[-1] == '\\' :
202
command += line[0:-1] + ' '
206
# add the last (current) line to the command
209
# push to raw history, so hist line numbers stay in sync
210
ip.IP.input_hist_raw.append("# " + command + "\n")
212
more = ip.IP.push(ip.IP.prefilter(command,more))
214
# IPython's runsource returns None if there was an error
215
# compiling the code. This allows us to stop processing right
216
# away, so the user gets the error message at the right place.
219
# final newline in case the input didn't have it, so that the code
220
# actually does get executed
224
ip.IP.runlines = _runlines