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