Show More
@@ -1,271 +1,268 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.core import ipapi |
|
10 | from IPython.core import ipapi | |
11 | from IPython.core.error import TryNext |
|
11 | from IPython.core.error import TryNext | |
12 | import os,re,textwrap |
|
12 | import os,re,textwrap | |
13 |
|
13 | |||
14 | # The import below effectively obsoletes your old-style ipythonrc[.ini], |
|
14 | # The import below effectively obsoletes your old-style ipythonrc[.ini], | |
15 | # so consider yourself warned! |
|
15 | # so consider yourself warned! | |
16 |
|
16 | |||
17 | import ipy_defaults |
|
17 | import ipy_defaults | |
18 |
|
18 | |||
19 | def main(): |
|
19 | def main(): | |
20 | ip = ipapi.get() |
|
20 | ip = ipapi.get() | |
21 | o = ip.options |
|
21 | o = ip.options | |
22 | # autocall to "full" mode (smart mode is default, I like full mode) |
|
22 | # autocall to "full" mode (smart mode is default, I like full mode) | |
23 |
|
23 | |||
24 | o.autocall = 2 |
|
24 | o.autocall = 2 | |
25 |
|
25 | |||
26 | # Jason Orendorff's path class is handy to have in user namespace |
|
26 | # Jason Orendorff's path class is handy to have in user namespace | |
27 | # if you are doing shell-like stuff |
|
27 | # if you are doing shell-like stuff | |
28 | try: |
|
28 | try: | |
29 | ip.ex("from IPython.external.path import path" ) |
|
29 | ip.ex("from IPython.external.path import path" ) | |
30 | except ImportError: |
|
30 | except ImportError: | |
31 | pass |
|
31 | pass | |
32 |
|
32 | |||
33 | # beefed up %env is handy in shell mode |
|
33 | # beefed up %env is handy in shell mode | |
34 | import envpersist |
|
34 | import envpersist | |
35 |
|
35 | |||
36 | # To see where mycmd resides (in path/aliases), do %which mycmd |
|
36 | # To see where mycmd resides (in path/aliases), do %which mycmd | |
37 | import ipy_which |
|
37 | import ipy_which | |
38 |
|
38 | |||
39 | # tab completers for hg, svn, ... |
|
39 | # tab completers for hg, svn, ... | |
40 | import ipy_app_completers |
|
40 | import ipy_app_completers | |
41 |
|
41 | |||
42 | # To make executables foo and bar in mybin usable without PATH change, do: |
|
42 | # To make executables foo and bar in mybin usable without PATH change, do: | |
43 | # %rehashdir c:/mybin |
|
43 | # %rehashdir c:/mybin | |
44 | # %store foo |
|
44 | # %store foo | |
45 | # %store bar |
|
45 | # %store bar | |
46 | import ipy_rehashdir |
|
46 | import ipy_rehashdir | |
47 |
|
47 | |||
48 | # does not work without subprocess module! |
|
48 | # does not work without subprocess module! | |
49 | #import ipy_signals |
|
49 | #import ipy_signals | |
50 |
|
50 | |||
51 | ip.ex('import os') |
|
51 | ip.ex('import os') | |
52 | ip.ex("def up(): os.chdir('..')") |
|
52 | ip.ex("def up(): os.chdir('..')") | |
53 | ip.user_ns['LA'] = LastArgFinder() |
|
53 | ip.user_ns['LA'] = LastArgFinder() | |
54 |
|
54 | |||
55 | # You can assign to _prompt_title variable |
|
55 | # You can assign to _prompt_title variable | |
56 | # to provide some extra information for prompt |
|
56 | # to provide some extra information for prompt | |
57 | # (e.g. the current mode, host/username...) |
|
57 | # (e.g. the current mode, host/username...) | |
58 |
|
58 | |||
59 | ip.user_ns['_prompt_title'] = '' |
|
59 | ip.user_ns['_prompt_title'] = '' | |
60 |
|
60 | |||
61 | # Nice prompt |
|
61 | # Nice prompt | |
62 | o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> ' |
|
62 | o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> ' | |
63 | o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> ' |
|
63 | o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> ' | |
64 | o.prompt_out= '<\#> ' |
|
64 | o.prompt_out= '<\#> ' | |
65 |
|
65 | |||
66 | from IPython.core import release |
|
66 | from IPython.core import release | |
67 |
|
67 | |||
68 | import sys |
|
68 | import sys | |
69 | # Non-chatty banner |
|
69 | # Non-chatty banner | |
70 | o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0]) |
|
70 | o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0]) | |
71 |
|
71 | |||
72 |
|
72 | |||
73 | ip.default_option('cd','-q') |
|
73 | ip.default_option('cd','-q') | |
74 | ip.default_option('macro', '-r') |
|
74 | ip.default_option('macro', '-r') | |
75 | # If you only rarely want to execute the things you %edit... |
|
75 | # If you only rarely want to execute the things you %edit... | |
76 | #ip.default_option('edit','-x') |
|
76 | #ip.default_option('edit','-x') | |
77 |
|
77 | |||
78 |
|
78 | |||
79 | o.prompts_pad_left="1" |
|
79 | o.prompts_pad_left="1" | |
80 | # Remove all blank lines in between prompts, like a normal shell. |
|
80 | # Remove all blank lines in between prompts, like a normal shell. | |
81 | o.separate_in="0" |
|
81 | o.separate_in="0" | |
82 | o.separate_out="0" |
|
82 | o.separate_out="0" | |
83 | o.separate_out2="0" |
|
83 | o.separate_out2="0" | |
84 |
|
84 | |||
85 | # now alias all syscommands |
|
85 | # now alias all syscommands | |
86 |
|
86 | |||
87 | db = ip.db |
|
87 | db = ip.db | |
88 |
|
88 | |||
89 | syscmds = db.get("syscmdlist",[] ) |
|
89 | syscmds = db.get("syscmdlist",[] ) | |
90 | if not syscmds: |
|
90 | if not syscmds: | |
91 | print textwrap.dedent(""" |
|
91 | print textwrap.dedent(""" | |
92 | System command list not initialized, probably the first run... |
|
92 | System command list not initialized, probably the first run... | |
93 | running %rehashx to refresh the command list. Run %rehashx |
|
93 | running %rehashx to refresh the command list. Run %rehashx | |
94 | again to refresh command list (after installing new software etc.) |
|
94 | again to refresh command list (after installing new software etc.) | |
95 | """) |
|
95 | """) | |
96 | ip.magic('rehashx') |
|
96 | ip.magic('rehashx') | |
97 | syscmds = db.get("syscmdlist") |
|
97 | syscmds = db.get("syscmdlist") | |
98 |
|
98 | |||
99 | # lowcase aliases on win32 only |
|
99 | # lowcase aliases on win32 only | |
100 | if os.name == 'posix': |
|
100 | if os.name == 'posix': | |
101 | mapper = lambda s:s |
|
101 | mapper = lambda s:s | |
102 | else: |
|
102 | else: | |
103 | def mapper(s): return s.lower() |
|
103 | def mapper(s): return s.lower() | |
104 |
|
104 | |||
105 | for cmd in syscmds: |
|
105 | for cmd in syscmds: | |
106 | # print "sys",cmd #dbg |
|
106 | # print "sys",cmd #dbg | |
107 | noext, ext = os.path.splitext(cmd) |
|
107 | noext, ext = os.path.splitext(cmd) | |
108 | if ext.lower() == '.exe': |
|
108 | if ext.lower() == '.exe': | |
109 | cmd = noext |
|
109 | cmd = noext | |
110 |
|
110 | |||
111 | key = mapper(cmd) |
|
111 | key = mapper(cmd) | |
112 | if key not in ip.alias_manager.alias_table: |
|
112 | if key not in ip.alias_manager.alias_table: | |
113 | # Dots will be removed from alias names, since ipython |
|
113 | # Dots will be removed from alias names, since ipython | |
114 | # assumes names with dots to be python code |
|
114 | # assumes names with dots to be python code | |
115 |
|
115 | |||
116 | ip.define_alias(key.replace('.',''), cmd) |
|
116 | ip.define_alias(key.replace('.',''), cmd) | |
117 |
|
117 | |||
118 | # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more |
|
|||
119 | ip.load("IPython.external.mglob") |
|
|||
120 |
|
||||
121 | # win32 is crippled w/o cygwin, try to help it a little bit |
|
118 | # win32 is crippled w/o cygwin, try to help it a little bit | |
122 | if sys.platform == 'win32': |
|
119 | if sys.platform == 'win32': | |
123 | if 'cygwin' in os.environ['PATH'].lower(): |
|
120 | if 'cygwin' in os.environ['PATH'].lower(): | |
124 | # use the colors of cygwin ls (recommended) |
|
121 | # use the colors of cygwin ls (recommended) | |
125 | ip.define_alias('d', 'ls -F --color=auto') |
|
122 | ip.define_alias('d', 'ls -F --color=auto') | |
126 | else: |
|
123 | else: | |
127 | # get icp, imv, imkdir, igrep, irm,... |
|
124 | # get icp, imv, imkdir, igrep, irm,... | |
128 | ip.load('ipy_fsops') |
|
125 | ip.load('ipy_fsops') | |
129 |
|
126 | |||
130 | # and the next best thing to real 'ls -F' |
|
127 | # and the next best thing to real 'ls -F' | |
131 | ip.define_alias('d','dir /w /og /on') |
|
128 | ip.define_alias('d','dir /w /og /on') | |
132 |
|
129 | |||
133 | ip.set_hook('input_prefilter', slash_prefilter_f) |
|
130 | ip.set_hook('input_prefilter', slash_prefilter_f) | |
134 | extend_shell_behavior(ip) |
|
131 | extend_shell_behavior(ip) | |
135 |
|
132 | |||
136 | class LastArgFinder: |
|
133 | class LastArgFinder: | |
137 | """ Allow $LA to work as "last argument of previous command", like $! in bash |
|
134 | """ Allow $LA to work as "last argument of previous command", like $! in bash | |
138 |
|
135 | |||
139 | To call this in normal IPython code, do LA() |
|
136 | To call this in normal IPython code, do LA() | |
140 | """ |
|
137 | """ | |
141 | def __call__(self, hist_idx = None): |
|
138 | def __call__(self, hist_idx = None): | |
142 | ip = ipapi.get() |
|
139 | ip = ipapi.get() | |
143 | if hist_idx is None: |
|
140 | if hist_idx is None: | |
144 | return str(self) |
|
141 | return str(self) | |
145 | return ip.input_hist_raw[hist_idx].strip().split()[-1] |
|
142 | return ip.input_hist_raw[hist_idx].strip().split()[-1] | |
146 | def __str__(self): |
|
143 | def __str__(self): | |
147 | ip = ipapi.get() |
|
144 | ip = ipapi.get() | |
148 | for cmd in reversed(ip.input_hist_raw): |
|
145 | for cmd in reversed(ip.input_hist_raw): | |
149 | parts = cmd.strip().split() |
|
146 | parts = cmd.strip().split() | |
150 | if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']: |
|
147 | if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']: | |
151 | continue |
|
148 | continue | |
152 | return parts[-1] |
|
149 | return parts[-1] | |
153 | return "" |
|
150 | return "" | |
154 |
|
151 | |||
155 | def slash_prefilter_f(self,line): |
|
152 | def slash_prefilter_f(self,line): | |
156 | """ ./foo, ~/foo and /bin/foo now run foo as system command |
|
153 | """ ./foo, ~/foo and /bin/foo now run foo as system command | |
157 |
|
154 | |||
158 | Removes the need for doing !./foo, !~/foo or !/bin/foo |
|
155 | Removes the need for doing !./foo, !~/foo or !/bin/foo | |
159 | """ |
|
156 | """ | |
160 | from IPython.utils import genutils |
|
157 | from IPython.utils import genutils | |
161 | if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line): |
|
158 | if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line): | |
162 | return "get_ipython().system(" + genutils.make_quoted_expr(line)+")" |
|
159 | return "get_ipython().system(" + genutils.make_quoted_expr(line)+")" | |
163 | raise TryNext |
|
160 | raise TryNext | |
164 |
|
161 | |||
165 | # XXX You do not need to understand the next function! |
|
162 | # XXX You do not need to understand the next function! | |
166 | # This should probably be moved out of profile |
|
163 | # This should probably be moved out of profile | |
167 |
|
164 | |||
168 | def extend_shell_behavior(ip): |
|
165 | def extend_shell_behavior(ip): | |
169 |
|
166 | |||
170 | # Instead of making signature a global variable tie it to IPSHELL. |
|
167 | # Instead of making signature a global variable tie it to IPSHELL. | |
171 | # In future if it is required to distinguish between different |
|
168 | # In future if it is required to distinguish between different | |
172 | # shells we can assign a signature per shell basis |
|
169 | # shells we can assign a signature per shell basis | |
173 | ip.__sig__ = 0xa005 |
|
170 | ip.__sig__ = 0xa005 | |
174 | # mark the IPSHELL with this signature |
|
171 | # mark the IPSHELL with this signature | |
175 | ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__ |
|
172 | ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__ | |
176 |
|
173 | |||
177 | from IPython.external.Itpl import ItplNS |
|
174 | from IPython.external.Itpl import ItplNS | |
178 | from IPython.utils.genutils import shell |
|
175 | from IPython.utils.genutils import shell | |
179 | # utility to expand user variables via Itpl |
|
176 | # utility to expand user variables via Itpl | |
180 | # xxx do something sensible with depth? |
|
177 | # xxx do something sensible with depth? | |
181 | ip.var_expand = lambda cmd, lvars=None, depth=2: \ |
|
178 | ip.var_expand = lambda cmd, lvars=None, depth=2: \ | |
182 | str(ItplNS(cmd, ip.user_ns, get_locals())) |
|
179 | str(ItplNS(cmd, ip.user_ns, get_locals())) | |
183 |
|
180 | |||
184 | def get_locals(): |
|
181 | def get_locals(): | |
185 | """ Substituting a variable through Itpl deep inside the IPSHELL stack |
|
182 | """ Substituting a variable through Itpl deep inside the IPSHELL stack | |
186 | requires the knowledge of all the variables in scope upto the last |
|
183 | requires the knowledge of all the variables in scope upto the last | |
187 | IPSHELL frame. This routine simply merges all the local variables |
|
184 | IPSHELL frame. This routine simply merges all the local variables | |
188 | on the IPSHELL stack without worrying about their scope rules |
|
185 | on the IPSHELL stack without worrying about their scope rules | |
189 | """ |
|
186 | """ | |
190 | import sys |
|
187 | import sys | |
191 | # note lambda expression constitues a function call |
|
188 | # note lambda expression constitues a function call | |
192 | # hence fno should be incremented by one |
|
189 | # hence fno should be incremented by one | |
193 | getsig = lambda fno: sys._getframe(fno+1).f_globals \ |
|
190 | getsig = lambda fno: sys._getframe(fno+1).f_globals \ | |
194 | ['__builtins__'].__dict__['__sig__'] |
|
191 | ['__builtins__'].__dict__['__sig__'] | |
195 | getlvars = lambda fno: sys._getframe(fno+1).f_locals |
|
192 | getlvars = lambda fno: sys._getframe(fno+1).f_locals | |
196 | # trackback until we enter the IPSHELL |
|
193 | # trackback until we enter the IPSHELL | |
197 | frame_no = 1 |
|
194 | frame_no = 1 | |
198 | sig = ip.__sig__ |
|
195 | sig = ip.__sig__ | |
199 | fsig = ~sig |
|
196 | fsig = ~sig | |
200 | while fsig != sig : |
|
197 | while fsig != sig : | |
201 | try: |
|
198 | try: | |
202 | fsig = getsig(frame_no) |
|
199 | fsig = getsig(frame_no) | |
203 | except (AttributeError, KeyError): |
|
200 | except (AttributeError, KeyError): | |
204 | frame_no += 1 |
|
201 | frame_no += 1 | |
205 | except ValueError: |
|
202 | except ValueError: | |
206 | # stack is depleted |
|
203 | # stack is depleted | |
207 | # call did not originate from IPSHELL |
|
204 | # call did not originate from IPSHELL | |
208 | return {} |
|
205 | return {} | |
209 | first_frame = frame_no |
|
206 | first_frame = frame_no | |
210 | # walk further back until we exit from IPSHELL or deplete stack |
|
207 | # walk further back until we exit from IPSHELL or deplete stack | |
211 | try: |
|
208 | try: | |
212 | while(sig == getsig(frame_no+1)): |
|
209 | while(sig == getsig(frame_no+1)): | |
213 | frame_no += 1 |
|
210 | frame_no += 1 | |
214 | except (AttributeError, KeyError, ValueError): |
|
211 | except (AttributeError, KeyError, ValueError): | |
215 | pass |
|
212 | pass | |
216 | # merge the locals from top down hence overriding |
|
213 | # merge the locals from top down hence overriding | |
217 | # any re-definitions of variables, functions etc. |
|
214 | # any re-definitions of variables, functions etc. | |
218 | lvars = {} |
|
215 | lvars = {} | |
219 | for fno in range(frame_no, first_frame-1, -1): |
|
216 | for fno in range(frame_no, first_frame-1, -1): | |
220 | lvars.update(getlvars(fno)) |
|
217 | lvars.update(getlvars(fno)) | |
221 | #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg |
|
218 | #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg | |
222 | return lvars |
|
219 | return lvars | |
223 |
|
220 | |||
224 | def _runlines(lines): |
|
221 | def _runlines(lines): | |
225 | """Run a string of one or more lines of source. |
|
222 | """Run a string of one or more lines of source. | |
226 |
|
223 | |||
227 | This method is capable of running a string containing multiple source |
|
224 | This method is capable of running a string containing multiple source | |
228 | lines, as if they had been entered at the IPython prompt. Since it |
|
225 | lines, as if they had been entered at the IPython prompt. Since it | |
229 | exposes IPython's processing machinery, the given strings can contain |
|
226 | exposes IPython's processing machinery, the given strings can contain | |
230 | magic calls (%magic), special shell access (!cmd), etc.""" |
|
227 | magic calls (%magic), special shell access (!cmd), etc.""" | |
231 |
|
228 | |||
232 | # We must start with a clean buffer, in case this is run from an |
|
229 | # We must start with a clean buffer, in case this is run from an | |
233 | # interactive IPython session (via a magic, for example). |
|
230 | # interactive IPython session (via a magic, for example). | |
234 | ip.resetbuffer() |
|
231 | ip.resetbuffer() | |
235 | lines = lines.split('\n') |
|
232 | lines = lines.split('\n') | |
236 | more = 0 |
|
233 | more = 0 | |
237 | command = '' |
|
234 | command = '' | |
238 | for line in lines: |
|
235 | for line in lines: | |
239 | # skip blank lines so we don't mess up the prompt counter, but do |
|
236 | # skip blank lines so we don't mess up the prompt counter, but do | |
240 | # NOT skip even a blank line if we are in a code block (more is |
|
237 | # NOT skip even a blank line if we are in a code block (more is | |
241 | # true) |
|
238 | # true) | |
242 | # if command is not empty trim the line |
|
239 | # if command is not empty trim the line | |
243 | if command != '' : |
|
240 | if command != '' : | |
244 | line = line.strip() |
|
241 | line = line.strip() | |
245 | # add the broken line to the command |
|
242 | # add the broken line to the command | |
246 | if line and line[-1] == '\\' : |
|
243 | if line and line[-1] == '\\' : | |
247 | command += line[0:-1] + ' ' |
|
244 | command += line[0:-1] + ' ' | |
248 | more = True |
|
245 | more = True | |
249 | continue |
|
246 | continue | |
250 | else : |
|
247 | else : | |
251 | # add the last (current) line to the command |
|
248 | # add the last (current) line to the command | |
252 | command += line |
|
249 | command += line | |
253 | if command or more: |
|
250 | if command or more: | |
254 | # push to raw history, so hist line numbers stay in sync |
|
251 | # push to raw history, so hist line numbers stay in sync | |
255 | ip.input_hist_raw.append("# " + command + "\n") |
|
252 | ip.input_hist_raw.append("# " + command + "\n") | |
256 |
|
253 | |||
257 | more = ip.push_line(ip.prefilter(command,more)) |
|
254 | more = ip.push_line(ip.prefilter(command,more)) | |
258 | command = '' |
|
255 | command = '' | |
259 | # IPython's runsource returns None if there was an error |
|
256 | # IPython's runsource returns None if there was an error | |
260 | # compiling the code. This allows us to stop processing right |
|
257 | # compiling the code. This allows us to stop processing right | |
261 | # away, so the user gets the error message at the right place. |
|
258 | # away, so the user gets the error message at the right place. | |
262 | if more is None: |
|
259 | if more is None: | |
263 | break |
|
260 | break | |
264 | # final newline in case the input didn't have it, so that the code |
|
261 | # final newline in case the input didn't have it, so that the code | |
265 | # actually does get executed |
|
262 | # actually does get executed | |
266 | if more: |
|
263 | if more: | |
267 | ip.push_line('\n') |
|
264 | ip.push_line('\n') | |
268 |
|
265 | |||
269 | ip.runlines = _runlines |
|
266 | ip.runlines = _runlines | |
270 |
|
267 | |||
271 | main() |
|
268 | main() |
@@ -1,246 +1,254 b'' | |||||
1 | """ File system operations |
|
1 | """ File system operations | |
2 |
|
2 | |||
3 | Contains: Simple variants of normal unix shell commands (icp, imv, irm, |
|
3 | Contains: Simple variants of normal unix shell commands (icp, imv, irm, | |
4 | imkdir, igrep). |
|
4 | imkdir, igrep). | |
5 |
|
5 | |||
6 | Some "otherwise handy" utils ('collect' for gathering files to |
|
6 | Some "otherwise handy" utils ('collect' for gathering files to | |
7 | ~/_ipython/collect, 'inote' for collecting single note lines to |
|
7 | ~/_ipython/collect, 'inote' for collecting single note lines to | |
8 | ~/_ipython/note.txt) |
|
8 | ~/_ipython/note.txt) | |
9 |
|
9 | |||
10 | Mostly of use for bare windows installations where cygwin/equivalent is not |
|
10 | Mostly of use for bare windows installations where cygwin/equivalent is not | |
11 | installed and you would otherwise need to deal with dos versions of the |
|
11 | installed and you would otherwise need to deal with dos versions of the | |
12 | commands (that e.g. don't understand / as path separator). These can |
|
12 | commands (that e.g. don't understand / as path separator). These can | |
13 | do some useful tricks on their own, though (like use 'mglob' patterns). |
|
13 | do some useful tricks on their own, though (like use 'mglob' patterns). | |
14 |
|
14 | |||
15 | Not to be confused with ipipe commands (ils etc.) that also start with i. |
|
15 | Not to be confused with ipipe commands (ils etc.) that also start with i. | |
|
16 | ||||
|
17 | QUARANTINE, NEEDS UPDATING TO THE NEW IPYTHON API TO WORK | |||
|
18 | ||||
|
19 | this depends on mglob that used to be in externals, | |||
|
20 | if this code is updated to run again with current IPython, you may need to | |||
|
21 | reintroduce that file back. In doing so, look for the possibility of achieving | |||
|
22 | the same effect only with the standard library (which may have improved by now, | |||
|
23 | since we currently depend on Python 2.6). | |||
16 | """ |
|
24 | """ | |
17 |
|
25 | |||
18 | from IPython.core import ipapi |
|
26 | from IPython.core import ipapi | |
19 | from IPython.core.error import TryNext |
|
27 | from IPython.core.error import TryNext | |
20 | ip = ipapi.get() |
|
28 | ip = ipapi.get() | |
21 |
|
29 | |||
22 | import shutil,os,shlex |
|
30 | import shutil,os,shlex | |
23 | from IPython.external import mglob |
|
31 | from IPython.external import mglob | |
24 | from IPython.external.path import path |
|
32 | from IPython.external.path import path | |
25 | from IPython.core.error import UsageError |
|
33 | from IPython.core.error import UsageError | |
26 | import IPython.utils.generics |
|
34 | import IPython.utils.generics | |
27 |
|
35 | |||
28 | def parse_args(args): |
|
36 | def parse_args(args): | |
29 | """ Given arg string 'CMD files... target', return ([files], target) """ |
|
37 | """ Given arg string 'CMD files... target', return ([files], target) """ | |
30 |
|
38 | |||
31 | tup = args.split(None, 1) |
|
39 | tup = args.split(None, 1) | |
32 | if len(tup) == 1: |
|
40 | if len(tup) == 1: | |
33 | raise UsageError("Expected arguments for " + tup[0]) |
|
41 | raise UsageError("Expected arguments for " + tup[0]) | |
34 |
|
42 | |||
35 | tup2 = shlex.split(tup[1]) |
|
43 | tup2 = shlex.split(tup[1]) | |
36 |
|
44 | |||
37 | flist, trg = mglob.expand(tup2[0:-1]), tup2[-1] |
|
45 | flist, trg = mglob.expand(tup2[0:-1]), tup2[-1] | |
38 | if not flist: |
|
46 | if not flist: | |
39 | raise UsageError("No files found:" + str(tup2[0:-1])) |
|
47 | raise UsageError("No files found:" + str(tup2[0:-1])) | |
40 | return flist, trg |
|
48 | return flist, trg | |
41 |
|
49 | |||
42 | def icp(ip,arg): |
|
50 | def icp(ip,arg): | |
43 | """ icp files... targetdir |
|
51 | """ icp files... targetdir | |
44 |
|
52 | |||
45 | Copy all files to target, creating dirs for target if necessary |
|
53 | Copy all files to target, creating dirs for target if necessary | |
46 |
|
54 | |||
47 | icp srcdir dstdir |
|
55 | icp srcdir dstdir | |
48 |
|
56 | |||
49 | Copy srcdir to distdir |
|
57 | Copy srcdir to distdir | |
50 |
|
58 | |||
51 | """ |
|
59 | """ | |
52 | import distutils.dir_util |
|
60 | import distutils.dir_util | |
53 |
|
61 | |||
54 | fs, targetdir = parse_args(arg) |
|
62 | fs, targetdir = parse_args(arg) | |
55 | if not os.path.isdir(targetdir) and len(fs) > 1: |
|
63 | if not os.path.isdir(targetdir) and len(fs) > 1: | |
56 | distutils.dir_util.mkpath(targetdir,verbose =1) |
|
64 | distutils.dir_util.mkpath(targetdir,verbose =1) | |
57 | for f in fs: |
|
65 | for f in fs: | |
58 | if os.path.isdir(f): |
|
66 | if os.path.isdir(f): | |
59 | shutil.copytree(f, targetdir) |
|
67 | shutil.copytree(f, targetdir) | |
60 | else: |
|
68 | else: | |
61 | shutil.copy2(f,targetdir) |
|
69 | shutil.copy2(f,targetdir) | |
62 | return fs |
|
70 | return fs | |
63 | ip.define_alias("icp",icp) |
|
71 | ip.define_alias("icp",icp) | |
64 |
|
72 | |||
65 | def imv(ip,arg): |
|
73 | def imv(ip,arg): | |
66 | """ imv src tgt |
|
74 | """ imv src tgt | |
67 |
|
75 | |||
68 | Move source to target. |
|
76 | Move source to target. | |
69 | """ |
|
77 | """ | |
70 |
|
78 | |||
71 | fs, target = parse_args(arg) |
|
79 | fs, target = parse_args(arg) | |
72 | if len(fs) > 1: |
|
80 | if len(fs) > 1: | |
73 | assert os.path.isdir(target) |
|
81 | assert os.path.isdir(target) | |
74 | for f in fs: |
|
82 | for f in fs: | |
75 | shutil.move(f, target) |
|
83 | shutil.move(f, target) | |
76 | return fs |
|
84 | return fs | |
77 | ip.define_alias("imv",imv) |
|
85 | ip.define_alias("imv",imv) | |
78 |
|
86 | |||
79 | def irm(ip,arg): |
|
87 | def irm(ip,arg): | |
80 | """ irm path[s]... |
|
88 | """ irm path[s]... | |
81 |
|
89 | |||
82 | Remove file[s] or dir[s] path. Dirs are deleted recursively. |
|
90 | Remove file[s] or dir[s] path. Dirs are deleted recursively. | |
83 | """ |
|
91 | """ | |
84 | try: |
|
92 | try: | |
85 | paths = mglob.expand(arg.split(None,1)[1]) |
|
93 | paths = mglob.expand(arg.split(None,1)[1]) | |
86 | except IndexError: |
|
94 | except IndexError: | |
87 | raise UsageError("%irm paths...") |
|
95 | raise UsageError("%irm paths...") | |
88 | import distutils.dir_util |
|
96 | import distutils.dir_util | |
89 | for p in paths: |
|
97 | for p in paths: | |
90 | print "rm",p |
|
98 | print "rm",p | |
91 | if os.path.isdir(p): |
|
99 | if os.path.isdir(p): | |
92 | distutils.dir_util.remove_tree(p, verbose = 1) |
|
100 | distutils.dir_util.remove_tree(p, verbose = 1) | |
93 | else: |
|
101 | else: | |
94 | os.remove(p) |
|
102 | os.remove(p) | |
95 |
|
103 | |||
96 | ip.define_alias("irm",irm) |
|
104 | ip.define_alias("irm",irm) | |
97 |
|
105 | |||
98 | def imkdir(ip,arg): |
|
106 | def imkdir(ip,arg): | |
99 | """ imkdir path |
|
107 | """ imkdir path | |
100 |
|
108 | |||
101 | Creates dir path, and all dirs on the road |
|
109 | Creates dir path, and all dirs on the road | |
102 | """ |
|
110 | """ | |
103 | import distutils.dir_util |
|
111 | import distutils.dir_util | |
104 | targetdir = arg.split(None,1)[1] |
|
112 | targetdir = arg.split(None,1)[1] | |
105 | distutils.dir_util.mkpath(targetdir,verbose =1) |
|
113 | distutils.dir_util.mkpath(targetdir,verbose =1) | |
106 |
|
114 | |||
107 | ip.define_alias("imkdir",imkdir) |
|
115 | ip.define_alias("imkdir",imkdir) | |
108 |
|
116 | |||
109 | def igrep(ip,arg): |
|
117 | def igrep(ip,arg): | |
110 | """ igrep PAT files... |
|
118 | """ igrep PAT files... | |
111 |
|
119 | |||
112 | Very dumb file scan, case-insensitive. |
|
120 | Very dumb file scan, case-insensitive. | |
113 |
|
121 | |||
114 | e.g. |
|
122 | e.g. | |
115 |
|
123 | |||
116 | igrep "test this" rec:*.py |
|
124 | igrep "test this" rec:*.py | |
117 |
|
125 | |||
118 | """ |
|
126 | """ | |
119 | elems = shlex.split(arg) |
|
127 | elems = shlex.split(arg) | |
120 | dummy, pat, fs = elems[0], elems[1], mglob.expand(elems[2:]) |
|
128 | dummy, pat, fs = elems[0], elems[1], mglob.expand(elems[2:]) | |
121 | res = [] |
|
129 | res = [] | |
122 | for f in fs: |
|
130 | for f in fs: | |
123 | found = False |
|
131 | found = False | |
124 | for l in open(f): |
|
132 | for l in open(f): | |
125 | if pat.lower() in l.lower(): |
|
133 | if pat.lower() in l.lower(): | |
126 | if not found: |
|
134 | if not found: | |
127 | print "[[",f,"]]" |
|
135 | print "[[",f,"]]" | |
128 | found = True |
|
136 | found = True | |
129 | res.append(f) |
|
137 | res.append(f) | |
130 | print l.rstrip() |
|
138 | print l.rstrip() | |
131 | return res |
|
139 | return res | |
132 |
|
140 | |||
133 | ip.define_alias("igrep",igrep) |
|
141 | ip.define_alias("igrep",igrep) | |
134 |
|
142 | |||
135 | def collect(ip,arg): |
|
143 | def collect(ip,arg): | |
136 | """ collect foo/a.txt rec:bar=*.py |
|
144 | """ collect foo/a.txt rec:bar=*.py | |
137 |
|
145 | |||
138 | Copies foo/a.txt to ~/_ipython/collect/foo/a.txt and *.py from bar, |
|
146 | Copies foo/a.txt to ~/_ipython/collect/foo/a.txt and *.py from bar, | |
139 | likewise |
|
147 | likewise | |
140 |
|
148 | |||
141 | Without args, try to open ~/_ipython/collect dir (in win32 at least). |
|
149 | Without args, try to open ~/_ipython/collect dir (in win32 at least). | |
142 | """ |
|
150 | """ | |
143 | from IPython.external.path import path |
|
151 | from IPython.external.path import path | |
144 | basedir = path(ip.ipython_dir + '/collect') |
|
152 | basedir = path(ip.ipython_dir + '/collect') | |
145 | try: |
|
153 | try: | |
146 | fs = mglob.expand(arg.split(None,1)[1]) |
|
154 | fs = mglob.expand(arg.split(None,1)[1]) | |
147 | except IndexError: |
|
155 | except IndexError: | |
148 | os.startfile(basedir) |
|
156 | os.startfile(basedir) | |
149 | return |
|
157 | return | |
150 | for f in fs: |
|
158 | for f in fs: | |
151 | f = path(f) |
|
159 | f = path(f) | |
152 | trg = basedir / f.splitdrive()[1].lstrip('/\\') |
|
160 | trg = basedir / f.splitdrive()[1].lstrip('/\\') | |
153 | if f.isdir(): |
|
161 | if f.isdir(): | |
154 | print "mkdir",trg |
|
162 | print "mkdir",trg | |
155 | trg.makedirs() |
|
163 | trg.makedirs() | |
156 | continue |
|
164 | continue | |
157 | dname = trg.dirname() |
|
165 | dname = trg.dirname() | |
158 | if not dname.isdir(): |
|
166 | if not dname.isdir(): | |
159 | dname.makedirs() |
|
167 | dname.makedirs() | |
160 | print f,"=>",trg |
|
168 | print f,"=>",trg | |
161 | shutil.copy2(f,trg) |
|
169 | shutil.copy2(f,trg) | |
162 |
|
170 | |||
163 | ip.define_alias("collect",collect) |
|
171 | ip.define_alias("collect",collect) | |
164 |
|
172 | |||
165 | def inote(ip,arg): |
|
173 | def inote(ip,arg): | |
166 | """ inote Hello world |
|
174 | """ inote Hello world | |
167 |
|
175 | |||
168 | Adds timestamp and Hello world to ~/_ipython/notes.txt |
|
176 | Adds timestamp and Hello world to ~/_ipython/notes.txt | |
169 |
|
177 | |||
170 | Without args, opens notes.txt for editing. |
|
178 | Without args, opens notes.txt for editing. | |
171 | """ |
|
179 | """ | |
172 | import time |
|
180 | import time | |
173 | fname = ip.ipython_dir + '/notes.txt' |
|
181 | fname = ip.ipython_dir + '/notes.txt' | |
174 |
|
182 | |||
175 | try: |
|
183 | try: | |
176 | entry = " === " + time.asctime() + ': ===\n' + arg.split(None,1)[1] + '\n' |
|
184 | entry = " === " + time.asctime() + ': ===\n' + arg.split(None,1)[1] + '\n' | |
177 | f= open(fname, 'a').write(entry) |
|
185 | f= open(fname, 'a').write(entry) | |
178 | except IndexError: |
|
186 | except IndexError: | |
179 | ip.hooks.editor(fname) |
|
187 | ip.hooks.editor(fname) | |
180 |
|
188 | |||
181 | ip.define_alias("inote",inote) |
|
189 | ip.define_alias("inote",inote) | |
182 |
|
190 | |||
183 | def pathobj_mangle(p): |
|
191 | def pathobj_mangle(p): | |
184 | return p.replace(' ', '__').replace('.','DOT') |
|
192 | return p.replace(' ', '__').replace('.','DOT') | |
185 | def pathobj_unmangle(s): |
|
193 | def pathobj_unmangle(s): | |
186 | return s.replace('__',' ').replace('DOT','.') |
|
194 | return s.replace('__',' ').replace('DOT','.') | |
187 |
|
195 | |||
188 |
|
196 | |||
189 |
|
197 | |||
190 | class PathObj(path): |
|
198 | class PathObj(path): | |
191 | def __init__(self,p): |
|
199 | def __init__(self,p): | |
192 | self.path = p |
|
200 | self.path = p | |
193 | if p != '.': |
|
201 | if p != '.': | |
194 | self.ents = [pathobj_mangle(ent) for ent in os.listdir(p)] |
|
202 | self.ents = [pathobj_mangle(ent) for ent in os.listdir(p)] | |
195 | else: |
|
203 | else: | |
196 | self.ents = None |
|
204 | self.ents = None | |
197 | def __complete__(self): |
|
205 | def __complete__(self): | |
198 | if self.path != '.': |
|
206 | if self.path != '.': | |
199 | return self.ents |
|
207 | return self.ents | |
200 | self.ents = [pathobj_mangle(ent) for ent in os.listdir('.')] |
|
208 | self.ents = [pathobj_mangle(ent) for ent in os.listdir('.')] | |
201 | return self.ents |
|
209 | return self.ents | |
202 | def __getattr__(self,name): |
|
210 | def __getattr__(self,name): | |
203 | if name in self.ents: |
|
211 | if name in self.ents: | |
204 | if self.path.endswith('/'): |
|
212 | if self.path.endswith('/'): | |
205 | sep = '' |
|
213 | sep = '' | |
206 | else: |
|
214 | else: | |
207 | sep = '/' |
|
215 | sep = '/' | |
208 |
|
216 | |||
209 | tgt = self.path + sep + pathobj_unmangle(name) |
|
217 | tgt = self.path + sep + pathobj_unmangle(name) | |
210 | #print "tgt",tgt |
|
218 | #print "tgt",tgt | |
211 | if os.path.isdir(tgt): |
|
219 | if os.path.isdir(tgt): | |
212 | return PathObj(tgt) |
|
220 | return PathObj(tgt) | |
213 | if os.path.isfile(tgt): |
|
221 | if os.path.isfile(tgt): | |
214 | return path(tgt) |
|
222 | return path(tgt) | |
215 |
|
223 | |||
216 | raise AttributeError, name # <<< DON'T FORGET THIS LINE !! |
|
224 | raise AttributeError, name # <<< DON'T FORGET THIS LINE !! | |
217 | def __str__(self): |
|
225 | def __str__(self): | |
218 | return self.path |
|
226 | return self.path | |
219 |
|
227 | |||
220 | def __repr__(self): |
|
228 | def __repr__(self): | |
221 | return "<PathObj to %s>" % self.path |
|
229 | return "<PathObj to %s>" % self.path | |
222 |
|
230 | |||
223 | def __call__(self): |
|
231 | def __call__(self): | |
224 | print "cd:",self.path |
|
232 | print "cd:",self.path | |
225 | os.chdir(self.path) |
|
233 | os.chdir(self.path) | |
226 |
|
234 | |||
227 | def complete_pathobj(obj, prev_completions): |
|
235 | def complete_pathobj(obj, prev_completions): | |
228 | if hasattr(obj,'__complete__'): |
|
236 | if hasattr(obj,'__complete__'): | |
229 | res = obj.__complete__() |
|
237 | res = obj.__complete__() | |
230 | if res: |
|
238 | if res: | |
231 | return res |
|
239 | return res | |
232 | # just return normal attributes of 'path' object if the dir is empty |
|
240 | # just return normal attributes of 'path' object if the dir is empty | |
233 | raise TryNext |
|
241 | raise TryNext | |
234 |
|
242 | |||
235 | complete_pathobj = IPython.utils.generics.complete_object.when_type(PathObj)(complete_pathobj) |
|
243 | complete_pathobj = IPython.utils.generics.complete_object.when_type(PathObj)(complete_pathobj) | |
236 |
|
244 | |||
237 | def test_pathobj(): |
|
245 | def test_pathobj(): | |
238 | #p = PathObj('c:/prj') |
|
246 | #p = PathObj('c:/prj') | |
239 | #p2 = p.cgi |
|
247 | #p2 = p.cgi | |
240 | #print p,p2 |
|
248 | #print p,p2 | |
241 | rootdir = PathObj("/") |
|
249 | rootdir = PathObj("/") | |
242 | startmenu = PathObj("d:/Documents and Settings/All Users/Start Menu/Programs") |
|
250 | startmenu = PathObj("d:/Documents and Settings/All Users/Start Menu/Programs") | |
243 | cwd = PathObj('.') |
|
251 | cwd = PathObj('.') | |
244 | ip.push("rootdir startmenu cwd") |
|
252 | ip.push("rootdir startmenu cwd") | |
245 |
|
253 | |||
246 | #test_pathobj() No newline at end of file |
|
254 | #test_pathobj() |
@@ -1,294 +1,283 b'' | |||||
1 | .. _ipython_as_shell: |
|
1 | .. _ipython_as_shell: | |
2 |
|
2 | |||
3 | ========================= |
|
3 | ========================= | |
4 | IPython as a system shell |
|
4 | IPython as a system shell | |
5 | ========================= |
|
5 | ========================= | |
6 |
|
6 | |||
7 | .. warning:: |
|
7 | .. warning:: | |
8 |
|
8 | |||
9 | As of the 0.11 version of IPython, most of the APIs used by the shell |
|
9 | As of the 0.11 version of IPython, most of the APIs used by the shell | |
10 | profile have been changed, so the profile currently does very little |
|
10 | profile have been changed, so the profile currently does very little | |
11 | beyond changing the IPython prompt. To help restore the shell |
|
11 | beyond changing the IPython prompt. To help restore the shell | |
12 | profile to past functionality described here, the old code is found in |
|
12 | profile to past functionality described here, the old code is found in | |
13 | :file:`IPython/deathrow`, which needs to be updated to use the |
|
13 | :file:`IPython/deathrow`, which needs to be updated to use the | |
14 | APIs in 0.11. |
|
14 | APIs in 0.11. | |
15 |
|
15 | |||
16 | Overview |
|
16 | Overview | |
17 | ======== |
|
17 | ======== | |
18 |
|
18 | |||
19 | The 'sh' profile optimizes IPython for system shell usage. Apart from |
|
19 | The 'sh' profile optimizes IPython for system shell usage. Apart from | |
20 | certain job control functionality that is present in unix (ctrl+z does |
|
20 | certain job control functionality that is present in unix (ctrl+z does | |
21 | "suspend"), the sh profile should provide you with most of the |
|
21 | "suspend"), the sh profile should provide you with most of the | |
22 | functionality you use daily in system shell, and more. Invoke IPython |
|
22 | functionality you use daily in system shell, and more. Invoke IPython | |
23 | in 'sh' profile by doing 'ipython -p sh', or (in win32) by launching |
|
23 | in 'sh' profile by doing 'ipython -p sh', or (in win32) by launching | |
24 | the "pysh" shortcut in start menu. |
|
24 | the "pysh" shortcut in start menu. | |
25 |
|
25 | |||
26 | If you want to use the features of sh profile as your defaults (which |
|
26 | If you want to use the features of sh profile as your defaults (which | |
27 | might be a good idea if you use other profiles a lot of the time but |
|
27 | might be a good idea if you use other profiles a lot of the time but | |
28 | still want the convenience of sh profile), add ``import ipy_profile_sh`` |
|
28 | still want the convenience of sh profile), add ``import ipy_profile_sh`` | |
29 | to your $IPYTHONDIR/ipy_user_conf.py. |
|
29 | to your $IPYTHONDIR/ipy_user_conf.py. | |
30 |
|
30 | |||
31 | The 'sh' profile is different from the default profile in that: |
|
31 | The 'sh' profile is different from the default profile in that: | |
32 |
|
32 | |||
33 | * Prompt shows the current directory |
|
33 | * Prompt shows the current directory | |
34 | * Spacing between prompts and input is more compact (no padding with |
|
34 | * Spacing between prompts and input is more compact (no padding with | |
35 | empty lines). The startup banner is more compact as well. |
|
35 | empty lines). The startup banner is more compact as well. | |
36 | * System commands are directly available (in alias table) without |
|
36 | * System commands are directly available (in alias table) without | |
37 | requesting %rehashx - however, if you install new programs along |
|
37 | requesting %rehashx - however, if you install new programs along | |
38 | your PATH, you might want to run %rehashx to update the persistent |
|
38 | your PATH, you might want to run %rehashx to update the persistent | |
39 | alias table |
|
39 | alias table | |
40 | * Macros are stored in raw format by default. That is, instead of |
|
40 | * Macros are stored in raw format by default. That is, instead of | |
41 | '_ip.system("cat foo"), the macro will contain text 'cat foo') |
|
41 | '_ip.system("cat foo"), the macro will contain text 'cat foo') | |
42 | * Autocall is in full mode |
|
42 | * Autocall is in full mode | |
43 | * Calling "up" does "cd .." |
|
43 | * Calling "up" does "cd .." | |
44 |
|
44 | |||
45 | The 'sh' profile is different from the now-obsolete (and unavailable) |
|
45 | The 'sh' profile is different from the now-obsolete (and unavailable) | |
46 | 'pysh' profile in that the ``$$var = command`` and ``$var = command`` syntax is |
|
46 | 'pysh' profile in that the ``$$var = command`` and ``$var = command`` syntax is | |
47 | not supported anymore. Use ``var = !command`` instead (which is available in all |
|
47 | not supported anymore. Use ``var = !command`` instead (which is available in all | |
48 | IPython profiles). |
|
48 | IPython profiles). | |
49 |
|
49 | |||
50 | Aliases |
|
50 | Aliases | |
51 | ======= |
|
51 | ======= | |
52 |
|
52 | |||
53 | All of your $PATH has been loaded as IPython aliases, so you should be |
|
53 | All of your $PATH has been loaded as IPython aliases, so you should be | |
54 | able to type any normal system command and have it executed. See |
|
54 | able to type any normal system command and have it executed. See | |
55 | %alias? and %unalias? for details on the alias facilities. See also |
|
55 | %alias? and %unalias? for details on the alias facilities. See also | |
56 | %rehashx? for details on the mechanism used to load $PATH. |
|
56 | %rehashx? for details on the mechanism used to load $PATH. | |
57 |
|
57 | |||
58 |
|
58 | |||
59 | Directory management |
|
59 | Directory management | |
60 | ==================== |
|
60 | ==================== | |
61 |
|
61 | |||
62 | Since each command passed by ipython to the underlying system is executed |
|
62 | Since each command passed by ipython to the underlying system is executed | |
63 | in a subshell which exits immediately, you can NOT use !cd to navigate |
|
63 | in a subshell which exits immediately, you can NOT use !cd to navigate | |
64 | the filesystem. |
|
64 | the filesystem. | |
65 |
|
65 | |||
66 | IPython provides its own builtin '%cd' magic command to move in the |
|
66 | IPython provides its own builtin '%cd' magic command to move in the | |
67 | filesystem (the % is not required with automagic on). It also maintains |
|
67 | filesystem (the % is not required with automagic on). It also maintains | |
68 | a list of visited directories (use %dhist to see it) and allows direct |
|
68 | a list of visited directories (use %dhist to see it) and allows direct | |
69 | switching to any of them. Type 'cd?' for more details. |
|
69 | switching to any of them. Type 'cd?' for more details. | |
70 |
|
70 | |||
71 | %pushd, %popd and %dirs are provided for directory stack handling. |
|
71 | %pushd, %popd and %dirs are provided for directory stack handling. | |
72 |
|
72 | |||
73 |
|
73 | |||
74 | Enabled extensions |
|
74 | Enabled extensions | |
75 | ================== |
|
75 | ================== | |
76 |
|
76 | |||
77 | Some extensions, listed below, are enabled as default in this profile. |
|
77 | Some extensions, listed below, are enabled as default in this profile. | |
78 |
|
78 | |||
79 | envpersist |
|
79 | envpersist | |
80 | ---------- |
|
80 | ---------- | |
81 |
|
81 | |||
82 | %env can be used to "remember" environment variable manipulations. Examples:: |
|
82 | %env can be used to "remember" environment variable manipulations. Examples:: | |
83 |
|
83 | |||
84 | %env - Show all environment variables |
|
84 | %env - Show all environment variables | |
85 | %env VISUAL=jed - set VISUAL to jed |
|
85 | %env VISUAL=jed - set VISUAL to jed | |
86 | %env PATH+=;/foo - append ;foo to PATH |
|
86 | %env PATH+=;/foo - append ;foo to PATH | |
87 | %env PATH+=;/bar - also append ;bar to PATH |
|
87 | %env PATH+=;/bar - also append ;bar to PATH | |
88 | %env PATH-=/wbin; - prepend /wbin; to PATH |
|
88 | %env PATH-=/wbin; - prepend /wbin; to PATH | |
89 | %env -d VISUAL - forget VISUAL persistent val |
|
89 | %env -d VISUAL - forget VISUAL persistent val | |
90 | %env -p - print all persistent env modifications |
|
90 | %env -p - print all persistent env modifications | |
91 |
|
91 | |||
92 | ipy_which |
|
92 | ipy_which | |
93 | --------- |
|
93 | --------- | |
94 |
|
94 | |||
95 | %which magic command. Like 'which' in unix, but knows about ipython aliases. |
|
95 | %which magic command. Like 'which' in unix, but knows about ipython aliases. | |
96 |
|
96 | |||
97 | Example:: |
|
97 | Example:: | |
98 |
|
98 | |||
99 | [C:/ipython]|14> %which st |
|
99 | [C:/ipython]|14> %which st | |
100 | st -> start . |
|
100 | st -> start . | |
101 | [C:/ipython]|15> %which d |
|
101 | [C:/ipython]|15> %which d | |
102 | d -> dir /w /og /on |
|
102 | d -> dir /w /og /on | |
103 | [C:/ipython]|16> %which cp |
|
103 | [C:/ipython]|16> %which cp | |
104 | cp -> cp |
|
104 | cp -> cp | |
105 | == c:\bin\cp.exe |
|
105 | == c:\bin\cp.exe | |
106 | c:\bin\cp.exe |
|
106 | c:\bin\cp.exe | |
107 |
|
107 | |||
108 | ipy_app_completers |
|
108 | ipy_app_completers | |
109 | ------------------ |
|
109 | ------------------ | |
110 |
|
110 | |||
111 | Custom tab completers for some apps like svn, hg, bzr, apt-get. Try 'apt-get install <TAB>' in debian/ubuntu. |
|
111 | Custom tab completers for some apps like svn, hg, bzr, apt-get. Try 'apt-get install <TAB>' in debian/ubuntu. | |
112 |
|
112 | |||
113 | ipy_rehashdir |
|
113 | ipy_rehashdir | |
114 | ------------- |
|
114 | ------------- | |
115 |
|
115 | |||
116 | Allows you to add system command aliases for commands that are not along your path. Let's say that you just installed Putty and want to be able to invoke it without adding it to path, you can create the alias for it with rehashdir:: |
|
116 | Allows you to add system command aliases for commands that are not along your path. Let's say that you just installed Putty and want to be able to invoke it without adding it to path, you can create the alias for it with rehashdir:: | |
117 |
|
117 | |||
118 | [~]|22> cd c:/opt/PuTTY/ |
|
118 | [~]|22> cd c:/opt/PuTTY/ | |
119 | [c:opt/PuTTY]|23> rehashdir . |
|
119 | [c:opt/PuTTY]|23> rehashdir . | |
120 | <23> ['pageant', 'plink', 'pscp', 'psftp', 'putty', 'puttygen', 'unins000'] |
|
120 | <23> ['pageant', 'plink', 'pscp', 'psftp', 'putty', 'puttygen', 'unins000'] | |
121 |
|
121 | |||
122 | Now, you can execute any of those commams directly:: |
|
122 | Now, you can execute any of those commams directly:: | |
123 |
|
123 | |||
124 | [c:opt/PuTTY]|24> cd |
|
124 | [c:opt/PuTTY]|24> cd | |
125 | [~]|25> putty |
|
125 | [~]|25> putty | |
126 |
|
126 | |||
127 | (the putty window opens). |
|
127 | (the putty window opens). | |
128 |
|
128 | |||
129 | If you want to store the alias so that it will always be available, do '%store putty'. If you want to %store all these aliases persistently, just do it in a for loop:: |
|
129 | If you want to store the alias so that it will always be available, do '%store putty'. If you want to %store all these aliases persistently, just do it in a for loop:: | |
130 |
|
130 | |||
131 | [~]|27> for a in _23: |
|
131 | [~]|27> for a in _23: | |
132 | |..> %store $a |
|
132 | |..> %store $a | |
133 | |..> |
|
133 | |..> | |
134 | |..> |
|
134 | |..> | |
135 | Alias stored: pageant (0, 'c:\\opt\\PuTTY\\pageant.exe') |
|
135 | Alias stored: pageant (0, 'c:\\opt\\PuTTY\\pageant.exe') | |
136 | Alias stored: plink (0, 'c:\\opt\\PuTTY\\plink.exe') |
|
136 | Alias stored: plink (0, 'c:\\opt\\PuTTY\\plink.exe') | |
137 | Alias stored: pscp (0, 'c:\\opt\\PuTTY\\pscp.exe') |
|
137 | Alias stored: pscp (0, 'c:\\opt\\PuTTY\\pscp.exe') | |
138 | Alias stored: psftp (0, 'c:\\opt\\PuTTY\\psftp.exe') |
|
138 | Alias stored: psftp (0, 'c:\\opt\\PuTTY\\psftp.exe') | |
139 | ... |
|
139 | ... | |
140 |
|
140 | |||
141 | mglob |
|
|||
142 | ----- |
|
|||
143 |
|
||||
144 | Provide the magic function %mglob, which makes it easier (than the 'find' command) to collect (possibly recursive) file lists. Examples:: |
|
|||
145 |
|
||||
146 | [c:/ipython]|9> mglob *.py |
|
|||
147 | [c:/ipython]|10> mglob *.py rec:*.txt |
|
|||
148 | [c:/ipython]|19> workfiles = %mglob !.svn/ !.hg/ !*_Data/ !*.bak rec:. |
|
|||
149 |
|
||||
150 | Note that the first 2 calls will put the file list in result history (_, _9, _10), and the last one will assign it to 'workfiles'. |
|
|||
151 |
|
||||
152 |
|
141 | |||
153 | Prompt customization |
|
142 | Prompt customization | |
154 | ==================== |
|
143 | ==================== | |
155 |
|
144 | |||
156 | The sh profile uses the following prompt configurations:: |
|
145 | The sh profile uses the following prompt configurations:: | |
157 |
|
146 | |||
158 | c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> ' |
|
147 | c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> ' | |
159 | c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> ' |
|
148 | c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> ' | |
160 | c.PromptManager.out_template = r'<\#> ' |
|
149 | c.PromptManager.out_template = r'<\#> ' | |
161 |
|
150 | |||
162 | You can change the prompt configuration to your liking by editing |
|
151 | You can change the prompt configuration to your liking by editing | |
163 | ipython_config.py. |
|
152 | ipython_config.py. | |
164 |
|
153 | |||
165 | .. _string_lists: |
|
154 | .. _string_lists: | |
166 |
|
155 | |||
167 | String lists |
|
156 | String lists | |
168 | ============ |
|
157 | ============ | |
169 |
|
158 | |||
170 | String lists (IPython.utils.text.SList) are handy way to process output |
|
159 | String lists (IPython.utils.text.SList) are handy way to process output | |
171 | from system commands. They are produced by ``var = !cmd`` syntax. |
|
160 | from system commands. They are produced by ``var = !cmd`` syntax. | |
172 |
|
161 | |||
173 | First, we acquire the output of 'ls -l':: |
|
162 | First, we acquire the output of 'ls -l':: | |
174 |
|
163 | |||
175 | [Q:doc/examples]|2> lines = !ls -l |
|
164 | [Q:doc/examples]|2> lines = !ls -l | |
176 | == |
|
165 | == | |
177 | ['total 23', |
|
166 | ['total 23', | |
178 | '-rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py', |
|
167 | '-rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py', | |
179 | '-rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py', |
|
168 | '-rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py', | |
180 | '-rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py', |
|
169 | '-rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py', | |
181 | '-rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py', |
|
170 | '-rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py', | |
182 | '-rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py', |
|
171 | '-rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py', | |
183 | '-rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py', |
|
172 | '-rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py', | |
184 | '-rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc'] |
|
173 | '-rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc'] | |
185 |
|
174 | |||
186 | Now, let's take a look at the contents of 'lines' (the first number is |
|
175 | Now, let's take a look at the contents of 'lines' (the first number is | |
187 | the list element number):: |
|
176 | the list element number):: | |
188 |
|
177 | |||
189 | [Q:doc/examples]|3> lines |
|
178 | [Q:doc/examples]|3> lines | |
190 | <3> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: |
|
179 | <3> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: | |
191 |
|
180 | |||
192 | 0: total 23 |
|
181 | 0: total 23 | |
193 | 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py |
|
182 | 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py | |
194 | 2: -rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py |
|
183 | 2: -rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py | |
195 | 3: -rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py |
|
184 | 3: -rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py | |
196 | 4: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py |
|
185 | 4: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py | |
197 | 5: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py |
|
186 | 5: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py | |
198 | 6: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py |
|
187 | 6: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py | |
199 | 7: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc |
|
188 | 7: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc | |
200 |
|
189 | |||
201 | Now, let's filter out the 'embed' lines:: |
|
190 | Now, let's filter out the 'embed' lines:: | |
202 |
|
191 | |||
203 | [Q:doc/examples]|4> l2 = lines.grep('embed',prune=1) |
|
192 | [Q:doc/examples]|4> l2 = lines.grep('embed',prune=1) | |
204 | [Q:doc/examples]|5> l2 |
|
193 | [Q:doc/examples]|5> l2 | |
205 | <5> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: |
|
194 | <5> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: | |
206 |
|
195 | |||
207 | 0: total 23 |
|
196 | 0: total 23 | |
208 | 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py |
|
197 | 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py | |
209 | 2: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py |
|
198 | 2: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py | |
210 | 3: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py |
|
199 | 3: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py | |
211 | 4: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py |
|
200 | 4: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py | |
212 | 5: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc |
|
201 | 5: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc | |
213 |
|
202 | |||
214 | Now, we want strings having just file names and permissions:: |
|
203 | Now, we want strings having just file names and permissions:: | |
215 |
|
204 | |||
216 | [Q:doc/examples]|6> l2.fields(8,0) |
|
205 | [Q:doc/examples]|6> l2.fields(8,0) | |
217 | <6> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: |
|
206 | <6> SList (.p, .n, .l, .s, .grep(), .fields() available). Value: | |
218 |
|
207 | |||
219 | 0: total |
|
208 | 0: total | |
220 | 1: example-demo.py -rw-rw-rw- |
|
209 | 1: example-demo.py -rw-rw-rw- | |
221 | 2: example-gnuplot.py -rwxrwxrwx |
|
210 | 2: example-gnuplot.py -rwxrwxrwx | |
222 | 3: extension.py -rwxrwxrwx |
|
211 | 3: extension.py -rwxrwxrwx | |
223 | 4: seteditor.py -rwxrwxrwx |
|
212 | 4: seteditor.py -rwxrwxrwx | |
224 | 5: seteditor.pyc -rwxrwxrwx |
|
213 | 5: seteditor.pyc -rwxrwxrwx | |
225 |
|
214 | |||
226 | Note how the line with 'total' does not raise IndexError. |
|
215 | Note how the line with 'total' does not raise IndexError. | |
227 |
|
216 | |||
228 | If you want to split these (yielding lists), call fields() without |
|
217 | If you want to split these (yielding lists), call fields() without | |
229 | arguments:: |
|
218 | arguments:: | |
230 |
|
219 | |||
231 | [Q:doc/examples]|7> _.fields() |
|
220 | [Q:doc/examples]|7> _.fields() | |
232 | <7> |
|
221 | <7> | |
233 | [['total'], |
|
222 | [['total'], | |
234 | ['example-demo.py', '-rw-rw-rw-'], |
|
223 | ['example-demo.py', '-rw-rw-rw-'], | |
235 | ['example-gnuplot.py', '-rwxrwxrwx'], |
|
224 | ['example-gnuplot.py', '-rwxrwxrwx'], | |
236 | ['extension.py', '-rwxrwxrwx'], |
|
225 | ['extension.py', '-rwxrwxrwx'], | |
237 | ['seteditor.py', '-rwxrwxrwx'], |
|
226 | ['seteditor.py', '-rwxrwxrwx'], | |
238 | ['seteditor.pyc', '-rwxrwxrwx']] |
|
227 | ['seteditor.pyc', '-rwxrwxrwx']] | |
239 |
|
228 | |||
240 | If you want to pass these separated with spaces to a command (typical |
|
229 | If you want to pass these separated with spaces to a command (typical | |
241 | for lists if files), use the .s property:: |
|
230 | for lists if files), use the .s property:: | |
242 |
|
231 | |||
243 |
|
232 | |||
244 | [Q:doc/examples]|13> files = l2.fields(8).s |
|
233 | [Q:doc/examples]|13> files = l2.fields(8).s | |
245 | [Q:doc/examples]|14> files |
|
234 | [Q:doc/examples]|14> files | |
246 | <14> 'example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc' |
|
235 | <14> 'example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc' | |
247 | [Q:doc/examples]|15> ls $files |
|
236 | [Q:doc/examples]|15> ls $files | |
248 | example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc |
|
237 | example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc | |
249 |
|
238 | |||
250 | SLists are inherited from normal python lists, so every list method is |
|
239 | SLists are inherited from normal python lists, so every list method is | |
251 | available:: |
|
240 | available:: | |
252 |
|
241 | |||
253 | [Q:doc/examples]|21> lines.append('hey') |
|
242 | [Q:doc/examples]|21> lines.append('hey') | |
254 |
|
243 | |||
255 |
|
244 | |||
256 | Real world example: remove all files outside version control |
|
245 | Real world example: remove all files outside version control | |
257 | ------------------------------------------------------------ |
|
246 | ------------------------------------------------------------ | |
258 |
|
247 | |||
259 | First, capture output of "hg status":: |
|
248 | First, capture output of "hg status":: | |
260 |
|
249 | |||
261 | [Q:/ipython]|28> out = !hg status |
|
250 | [Q:/ipython]|28> out = !hg status | |
262 | == |
|
251 | == | |
263 | ['M IPython\\extensions\\ipy_kitcfg.py', |
|
252 | ['M IPython\\extensions\\ipy_kitcfg.py', | |
264 | 'M IPython\\extensions\\ipy_rehashdir.py', |
|
253 | 'M IPython\\extensions\\ipy_rehashdir.py', | |
265 | ... |
|
254 | ... | |
266 | '? build\\lib\\IPython\\Debugger.py', |
|
255 | '? build\\lib\\IPython\\Debugger.py', | |
267 | '? build\\lib\\IPython\\extensions\\InterpreterExec.py', |
|
256 | '? build\\lib\\IPython\\extensions\\InterpreterExec.py', | |
268 | '? build\\lib\\IPython\\extensions\\InterpreterPasteInput.py', |
|
257 | '? build\\lib\\IPython\\extensions\\InterpreterPasteInput.py', | |
269 | ... |
|
258 | ... | |
270 |
|
259 | |||
271 | (lines starting with ? are not under version control). |
|
260 | (lines starting with ? are not under version control). | |
272 |
|
261 | |||
273 | :: |
|
262 | :: | |
274 |
|
263 | |||
275 | [Q:/ipython]|35> junk = out.grep(r'^\?').fields(1) |
|
264 | [Q:/ipython]|35> junk = out.grep(r'^\?').fields(1) | |
276 | [Q:/ipython]|36> junk |
|
265 | [Q:/ipython]|36> junk | |
277 | <36> SList (.p, .n, .l, .s, .grep(), .fields() availab |
|
266 | <36> SList (.p, .n, .l, .s, .grep(), .fields() availab | |
278 | ... |
|
267 | ... | |
279 | 10: build\bdist.win32\winexe\temp\_ctypes.py |
|
268 | 10: build\bdist.win32\winexe\temp\_ctypes.py | |
280 | 11: build\bdist.win32\winexe\temp\_hashlib.py |
|
269 | 11: build\bdist.win32\winexe\temp\_hashlib.py | |
281 | 12: build\bdist.win32\winexe\temp\_socket.py |
|
270 | 12: build\bdist.win32\winexe\temp\_socket.py | |
282 |
|
271 | |||
283 | Now we can just remove these files by doing 'rm $junk.s'. |
|
272 | Now we can just remove these files by doing 'rm $junk.s'. | |
284 |
|
273 | |||
285 | The .s, .n, .p properties |
|
274 | The .s, .n, .p properties | |
286 | ------------------------- |
|
275 | ------------------------- | |
287 |
|
276 | |||
288 | The ``.s`` property returns one string where lines are separated by |
|
277 | The ``.s`` property returns one string where lines are separated by | |
289 | single space (for convenient passing to system commands). The ``.n`` |
|
278 | single space (for convenient passing to system commands). The ``.n`` | |
290 | property return one string where the lines are separated by a newline |
|
279 | property return one string where the lines are separated by a newline | |
291 | (i.e. the original output of the function). If the items in string |
|
280 | (i.e. the original output of the function). If the items in string | |
292 | list are file names, ``.p`` can be used to get a list of "path" objects |
|
281 | list are file names, ``.p`` can be used to get a list of "path" objects | |
293 | for convenient file manipulation. |
|
282 | for convenient file manipulation. | |
294 |
|
283 |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now