##// END OF EJS Templates
disable ipy_signals in sh profile, it does not work with python 2.3 (that has no subprocess module)
Ville M. Vainio -
Show More
@@ -1,249 +1,251 b''
1 1 """Shell mode for IPython.
2 2
3 3 Start ipython in shell mode by invoking "ipython -p sh"
4 4
5 5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 6 shell mode and is recommended for users who don't care about pysh-mode
7 7 compatibility)
8 8 """
9 9
10 10 from IPython import ipapi
11 11 import os,textwrap
12 12
13 13 # The import below effectively obsoletes your old-style ipythonrc[.ini],
14 14 # so consider yourself warned!
15 15
16 16 import ipy_defaults
17 17
18 18 def main():
19 19 ip = ipapi.get()
20 20 o = ip.options
21 21 # autocall to "full" mode (smart mode is default, I like full mode)
22 22
23 23 o.autocall = 2
24 24
25 25 # Jason Orendorff's path class is handy to have in user namespace
26 26 # if you are doing shell-like stuff
27 27 try:
28 28 ip.ex("from IPython.external.path import path" )
29 29 except ImportError:
30 30 pass
31 31
32 32 # beefed up %env is handy in shell mode
33 33 import envpersist
34 34
35 35 # To see where mycmd resides (in path/aliases), do %which mycmd
36 36 import ipy_which
37 37
38 38 # tab completers for hg, svn, ...
39 39 import ipy_app_completers
40 40
41 41 # To make executables foo and bar in mybin usable without PATH change, do:
42 42 # %rehashdir c:/mybin
43 43 # %store foo
44 44 # %store bar
45 45 import ipy_rehashdir
46 import ipy_signals
46
47 # does not work without subprocess module!
48 #import ipy_signals
47 49
48 50 ip.ex('import os')
49 51 ip.ex("def up(): os.chdir('..')")
50 52 ip.user_ns['LA'] = LastArgFinder()
51 53 # Nice prompt
52 54
53 55 o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
54 56 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
55 57 o.prompt_out= '<\#> '
56 58
57 59 from IPython import Release
58 60
59 61 import sys
60 62 # Non-chatty banner
61 63 o.banner = "IPython %s [on Py %s]\n" % (Release.version,sys.version.split(None,1)[0])
62 64
63 65
64 66 ip.IP.default_option('cd','-q')
65 67 ip.IP.default_option('macro', '-r')
66 68 # If you only rarely want to execute the things you %edit...
67 69 #ip.IP.default_option('edit','-x')
68 70
69 71
70 72 o.prompts_pad_left="1"
71 73 # Remove all blank lines in between prompts, like a normal shell.
72 74 o.separate_in="0"
73 75 o.separate_out="0"
74 76 o.separate_out2="0"
75 77
76 78 # now alias all syscommands
77 79
78 80 db = ip.db
79 81
80 82 syscmds = db.get("syscmdlist",[] )
81 83 if not syscmds:
82 84 print textwrap.dedent("""
83 85 System command list not initialized, probably the first run...
84 86 running %rehashx to refresh the command list. Run %rehashx
85 87 again to refresh command list (after installing new software etc.)
86 88 """)
87 89 ip.magic('rehashx')
88 90 syscmds = db.get("syscmdlist")
89 91
90 92 # lowcase aliases on win32 only
91 93 if os.name == 'posix':
92 94 mapper = lambda s:s
93 95 else:
94 96 def mapper(s): return s.lower()
95 97
96 98 for cmd in syscmds:
97 99 # print "sys",cmd #dbg
98 100 noext, ext = os.path.splitext(cmd)
99 101 key = mapper(noext)
100 102 if key not in ip.IP.alias_table:
101 103 ip.defalias(key, cmd)
102 104
103 105 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
104 106 ip.load("IPython.external.mglob")
105 107
106 108 # win32 is crippled w/o cygwin, try to help it a little bit
107 109 if sys.platform == 'win32':
108 110 if 'cygwin' in os.environ['PATH'].lower():
109 111 # use the colors of cygwin ls (recommended)
110 112 ip.defalias('d', 'ls -F --color=auto')
111 113 else:
112 114 # get icp, imv, imkdir, igrep, irm,...
113 115 ip.load('ipy_fsops')
114 116
115 117 # and the next best thing to real 'ls -F'
116 118 ip.defalias('d','dir /w /og /on')
117 119
118 120 extend_shell_behavior(ip)
119 121
120 122 class LastArgFinder:
121 123 """ Allow $LA to work as "last argument of previous command", like $! in bash
122 124
123 125 To call this in normal IPython code, do LA()
124 126 """
125 127 def __call__(self, hist_idx = None):
126 128 ip = ipapi.get()
127 129 if hist_idx is None:
128 130 return str(self)
129 131 return ip.IP.input_hist_raw[hist_idx].strip().split()[-1]
130 132 def __str__(self):
131 133 ip = ipapi.get()
132 134 for cmd in reversed(ip.IP.input_hist_raw):
133 135 parts = cmd.strip().split()
134 136 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
135 137 continue
136 138 return parts[-1]
137 139 return ""
138 140
139 141
140 142
141 143
142 144
143 145 # XXX You do not need to understand the next function!
144 146 # This should probably be moved out of profile
145 147
146 148 def extend_shell_behavior(ip):
147 149
148 150 # Instead of making signature a global variable tie it to IPSHELL.
149 151 # In future if it is required to distinguish between different
150 152 # shells we can assign a signature per shell basis
151 153 ip.IP.__sig__ = 0xa005
152 154 # mark the IPSHELL with this signature
153 155 ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
154 156
155 157 from IPython.Itpl import ItplNS
156 158 from IPython.genutils import shell
157 159 # utility to expand user variables via Itpl
158 160 # xxx do something sensible with depth?
159 161 ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
160 162 str(ItplNS(cmd, ip.IP.user_ns, get_locals()))
161 163
162 164 def get_locals():
163 165 """ Substituting a variable through Itpl deep inside the IPSHELL stack
164 166 requires the knowledge of all the variables in scope upto the last
165 167 IPSHELL frame. This routine simply merges all the local variables
166 168 on the IPSHELL stack without worrying about their scope rules
167 169 """
168 170 import sys
169 171 # note lambda expression constitues a function call
170 172 # hence fno should be incremented by one
171 173 getsig = lambda fno: sys._getframe(fno+1).f_globals \
172 174 ['__builtins__'].__dict__['__sig__']
173 175 getlvars = lambda fno: sys._getframe(fno+1).f_locals
174 176 # trackback until we enter the IPSHELL
175 177 frame_no = 1
176 178 sig = ip.IP.__sig__
177 179 fsig = ~sig
178 180 while fsig != sig :
179 181 try:
180 182 fsig = getsig(frame_no)
181 183 except (AttributeError, KeyError):
182 184 frame_no += 1
183 185 except ValueError:
184 186 # stack is depleted
185 187 # call did not originate from IPSHELL
186 188 return {}
187 189 first_frame = frame_no
188 190 # walk further back until we exit from IPSHELL or deplete stack
189 191 try:
190 192 while(sig == getsig(frame_no+1)):
191 193 frame_no += 1
192 194 except (AttributeError, KeyError, ValueError):
193 195 pass
194 196 # merge the locals from top down hence overriding
195 197 # any re-definitions of variables, functions etc.
196 198 lvars = {}
197 199 for fno in range(frame_no, first_frame-1, -1):
198 200 lvars.update(getlvars(fno))
199 201 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
200 202 return lvars
201 203
202 204 def _runlines(lines):
203 205 """Run a string of one or more lines of source.
204 206
205 207 This method is capable of running a string containing multiple source
206 208 lines, as if they had been entered at the IPython prompt. Since it
207 209 exposes IPython's processing machinery, the given strings can contain
208 210 magic calls (%magic), special shell access (!cmd), etc."""
209 211
210 212 # We must start with a clean buffer, in case this is run from an
211 213 # interactive IPython session (via a magic, for example).
212 214 ip.IP.resetbuffer()
213 215 lines = lines.split('\n')
214 216 more = 0
215 217 command = ''
216 218 for line in lines:
217 219 # skip blank lines so we don't mess up the prompt counter, but do
218 220 # NOT skip even a blank line if we are in a code block (more is
219 221 # true)
220 222 # if command is not empty trim the line
221 223 if command != '' :
222 224 line = line.strip()
223 225 # add the broken line to the command
224 226 if line and line[-1] == '\\' :
225 227 command += line[0:-1] + ' '
226 228 more = True
227 229 continue
228 230 else :
229 231 # add the last (current) line to the command
230 232 command += line
231 233 if command or more:
232 234 # push to raw history, so hist line numbers stay in sync
233 235 ip.IP.input_hist_raw.append("# " + command + "\n")
234 236
235 237 more = ip.IP.push(ip.IP.prefilter(command,more))
236 238 command = ''
237 239 # IPython's runsource returns None if there was an error
238 240 # compiling the code. This allows us to stop processing right
239 241 # away, so the user gets the error message at the right place.
240 242 if more is None:
241 243 break
242 244 # final newline in case the input didn't have it, so that the code
243 245 # actually does get executed
244 246 if more:
245 247 ip.IP.push('\n')
246 248
247 249 ip.IP.runlines = _runlines
248 250
249 251 main()
General Comments 0
You need to be logged in to leave comments. Login now