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