##// END OF EJS Templates
d == ls -F --color==auto only if 'ls' is available
vivainio -
Show More
@@ -1,205 +1,208 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 path import path" )
28 ip.ex("from 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 import ipy_which
34 import ipy_which
35 import ipy_app_completers
35 import ipy_app_completers
36 import ipy_rehashdir
36 import ipy_rehashdir
37 import ipy_signals
37 import ipy_signals
38
38
39
39
40 ip.ex('import os')
40 ip.ex('import os')
41 ip.ex("def up(): os.chdir('..')")
41 ip.ex("def up(): os.chdir('..')")
42
42
43 # Nice prompt
43 # Nice prompt
44
44
45 o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
45 o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
46 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
46 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
47 o.prompt_out= '<\#> '
47 o.prompt_out= '<\#> '
48
48
49 from IPython import Release
49 from IPython import Release
50
50
51 import sys
51 import sys
52 # I like my banner minimal.
52 # I like my banner minimal.
53 o.banner = "IPython %s [on Py %s]\n" % (Release.version,sys.version.split(None,1)[0])
53 o.banner = "IPython %s [on Py %s]\n" % (Release.version,sys.version.split(None,1)[0])
54
54
55 # make 'd' an alias for ls -F
55 # make 'd' an alias for ls -F
56
56
57 # ip.magic('alias d ls -F --color=auto')
57 # ip.magic('alias d ls -F --color=auto')
58
58
59 ip.IP.default_option('cd','-q')
59 ip.IP.default_option('cd','-q')
60
60
61 # If you only rarely want to execute the things you %edit...
61 # If you only rarely want to execute the things you %edit...
62
62
63 #ip.IP.default_option('edit','-x')
63 #ip.IP.default_option('edit','-x')
64
64
65
65
66 o.prompts_pad_left="1"
66 o.prompts_pad_left="1"
67 # Remove all blank lines in between prompts, like a normal shell.
67 # Remove all blank lines in between prompts, like a normal shell.
68 o.separate_in="0"
68 o.separate_in="0"
69 o.separate_out="0"
69 o.separate_out="0"
70 o.separate_out2="0"
70 o.separate_out2="0"
71
71
72 # now alias all syscommands
72 # now alias all syscommands
73
73
74 db = ip.db
74 db = ip.db
75
75
76 syscmds = db.get("syscmdlist",[] )
76 syscmds = db.get("syscmdlist",[] )
77 if not syscmds:
77 if not syscmds:
78 print textwrap.dedent("""
78 print textwrap.dedent("""
79 System command list not initialized, probably the first run...
79 System command list not initialized, probably the first run...
80 running %rehashx to refresh the command list. Run %rehashx
80 running %rehashx to refresh the command list. Run %rehashx
81 again to refresh command list (after installing new software etc.)
81 again to refresh command list (after installing new software etc.)
82 """)
82 """)
83 ip.magic('rehashx')
83 ip.magic('rehashx')
84 syscmds = db.get("syscmdlist")
84 syscmds = db.get("syscmdlist")
85
85
86 # locase aliases on win#2 only
86 # locase aliases on win#2 only
87 if os.name == 'posix':
87 if os.name == 'posix':
88 mapper = lambda s:s
88 mapper = lambda s:s
89 else:
89 else:
90 def mapper(s): return s.lower()
90 def mapper(s): return s.lower()
91
91
92 for cmd in syscmds:
92 for cmd in syscmds:
93 #print "al",cmd
93 #print "al",cmd
94 noext, ext = os.path.splitext(cmd)
94 noext, ext = os.path.splitext(cmd)
95 ip.IP.alias_table[mapper(noext)] = (0,cmd)
95 ip.IP.alias_table[mapper(noext)] = (0,cmd)
96
96
97 if 'ls' in syscmds:
98 # use the colors of cygwin ls (recommended)
99 ip.magic('alias d ls -F --color=auto')
97 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
100 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
98 ip.load("IPython.external.mglob")
101 ip.load("IPython.external.mglob")
99
102
100 extend_shell_behavior(ip)
103 extend_shell_behavior(ip)
101
104
102 # XXX You do not need to understand the next function!
105 # XXX You do not need to understand the next function!
103 # This should probably be moved out of profile
106 # This should probably be moved out of profile
104
107
105 def extend_shell_behavior(ip):
108 def extend_shell_behavior(ip):
106
109
107 # Instead of making signature a global variable tie it to IPSHELL.
110 # Instead of making signature a global variable tie it to IPSHELL.
108 # In future if it is required to distinguish between different
111 # In future if it is required to distinguish between different
109 # shells we can assign a signature per shell basis
112 # shells we can assign a signature per shell basis
110 ip.IP.__sig__ = 0xa005
113 ip.IP.__sig__ = 0xa005
111 # mark the IPSHELL with this signature
114 # mark the IPSHELL with this signature
112 ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
115 ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
113
116
114 from IPython.Itpl import ItplNS
117 from IPython.Itpl import ItplNS
115 from IPython.genutils import shell
118 from IPython.genutils import shell
116 # utility to expand user variables via Itpl
119 # utility to expand user variables via Itpl
117 # xxx do something sensible with depth?
120 # xxx do something sensible with depth?
118 ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
121 ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
119 str(ItplNS(cmd.replace('#','\#'), ip.IP.user_ns, get_locals()))
122 str(ItplNS(cmd.replace('#','\#'), ip.IP.user_ns, get_locals()))
120
123
121 def get_locals():
124 def get_locals():
122 """ Substituting a variable through Itpl deep inside the IPSHELL stack
125 """ Substituting a variable through Itpl deep inside the IPSHELL stack
123 requires the knowledge of all the variables in scope upto the last
126 requires the knowledge of all the variables in scope upto the last
124 IPSHELL frame. This routine simply merges all the local variables
127 IPSHELL frame. This routine simply merges all the local variables
125 on the IPSHELL stack without worrying about their scope rules
128 on the IPSHELL stack without worrying about their scope rules
126 """
129 """
127 import sys
130 import sys
128 # note lambda expression constitues a function call
131 # note lambda expression constitues a function call
129 # hence fno should be incremented by one
132 # hence fno should be incremented by one
130 getsig = lambda fno: sys._getframe(fno+1).f_globals \
133 getsig = lambda fno: sys._getframe(fno+1).f_globals \
131 ['__builtins__'].__dict__['__sig__']
134 ['__builtins__'].__dict__['__sig__']
132 getlvars = lambda fno: sys._getframe(fno+1).f_locals
135 getlvars = lambda fno: sys._getframe(fno+1).f_locals
133 # trackback until we enter the IPSHELL
136 # trackback until we enter the IPSHELL
134 frame_no = 1
137 frame_no = 1
135 sig = ip.IP.__sig__
138 sig = ip.IP.__sig__
136 fsig = ~sig
139 fsig = ~sig
137 while fsig != sig :
140 while fsig != sig :
138 try:
141 try:
139 fsig = getsig(frame_no)
142 fsig = getsig(frame_no)
140 except (AttributeError, KeyError):
143 except (AttributeError, KeyError):
141 frame_no += 1
144 frame_no += 1
142 except ValueError:
145 except ValueError:
143 # stack is depleted
146 # stack is depleted
144 # call did not originate from IPSHELL
147 # call did not originate from IPSHELL
145 return {}
148 return {}
146 first_frame = frame_no
149 first_frame = frame_no
147 # walk further back until we exit from IPSHELL or deplete stack
150 # walk further back until we exit from IPSHELL or deplete stack
148 try:
151 try:
149 while(sig == getsig(frame_no+1)):
152 while(sig == getsig(frame_no+1)):
150 frame_no += 1
153 frame_no += 1
151 except (AttributeError, KeyError, ValueError):
154 except (AttributeError, KeyError, ValueError):
152 pass
155 pass
153 # merge the locals from top down hence overriding
156 # merge the locals from top down hence overriding
154 # any re-definitions of variables, functions etc.
157 # any re-definitions of variables, functions etc.
155 lvars = {}
158 lvars = {}
156 for fno in range(frame_no, first_frame-1, -1):
159 for fno in range(frame_no, first_frame-1, -1):
157 lvars.update(getlvars(fno))
160 lvars.update(getlvars(fno))
158 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
161 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
159 return lvars
162 return lvars
160
163
161 def _runlines(lines):
164 def _runlines(lines):
162 """Run a string of one or more lines of source.
165 """Run a string of one or more lines of source.
163
166
164 This method is capable of running a string containing multiple source
167 This method is capable of running a string containing multiple source
165 lines, as if they had been entered at the IPython prompt. Since it
168 lines, as if they had been entered at the IPython prompt. Since it
166 exposes IPython's processing machinery, the given strings can contain
169 exposes IPython's processing machinery, the given strings can contain
167 magic calls (%magic), special shell access (!cmd), etc."""
170 magic calls (%magic), special shell access (!cmd), etc."""
168
171
169 # We must start with a clean buffer, in case this is run from an
172 # We must start with a clean buffer, in case this is run from an
170 # interactive IPython session (via a magic, for example).
173 # interactive IPython session (via a magic, for example).
171 ip.IP.resetbuffer()
174 ip.IP.resetbuffer()
172 lines = lines.split('\n')
175 lines = lines.split('\n')
173 more = 0
176 more = 0
174 command = ''
177 command = ''
175 for line in lines:
178 for line in lines:
176 # skip blank lines so we don't mess up the prompt counter, but do
179 # skip blank lines so we don't mess up the prompt counter, but do
177 # NOT skip even a blank line if we are in a code block (more is
180 # NOT skip even a blank line if we are in a code block (more is
178 # true)
181 # true)
179 # if command is not empty trim the line
182 # if command is not empty trim the line
180 if command != '' :
183 if command != '' :
181 line = line.strip()
184 line = line.strip()
182 # add the broken line to the command
185 # add the broken line to the command
183 if line and line[-1] == '\\' :
186 if line and line[-1] == '\\' :
184 command += line[0:-1] + ' '
187 command += line[0:-1] + ' '
185 more = True
188 more = True
186 continue
189 continue
187 else :
190 else :
188 # add the last (current) line to the command
191 # add the last (current) line to the command
189 command += line
192 command += line
190 if command or more:
193 if command or more:
191 more = ip.IP.push(ip.IP.prefilter(command,more))
194 more = ip.IP.push(ip.IP.prefilter(command,more))
192 command = ''
195 command = ''
193 # IPython's runsource returns None if there was an error
196 # IPython's runsource returns None if there was an error
194 # compiling the code. This allows us to stop processing right
197 # compiling the code. This allows us to stop processing right
195 # away, so the user gets the error message at the right place.
198 # away, so the user gets the error message at the right place.
196 if more is None:
199 if more is None:
197 break
200 break
198 # final newline in case the input didn't have it, so that the code
201 # final newline in case the input didn't have it, so that the code
199 # actually does get executed
202 # actually does get executed
200 if more:
203 if more:
201 ip.IP.push('\n')
204 ip.IP.push('\n')
202
205
203 ip.IP.runlines = _runlines
206 ip.IP.runlines = _runlines
204
207
205 main()
208 main()
General Comments 0
You need to be logged in to leave comments. Login now