##// END OF EJS Templates
Update osm.py
hongshaoyang -
Show More
@@ -1,793 +1,793 b''
1 """Implementation of magic functions for interaction with the OS.
1 """Implementation of magic functions for interaction with the OS.
2
2
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 builtin.
4 builtin.
5 """
5 """
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import io
9 import io
10 import os
10 import os
11 import re
11 import re
12 import sys
12 import sys
13 from pprint import pformat
13 from pprint import pformat
14
14
15 from IPython.core import magic_arguments
15 from IPython.core import magic_arguments
16 from IPython.core import oinspect
16 from IPython.core import oinspect
17 from IPython.core import page
17 from IPython.core import page
18 from IPython.core.alias import AliasError, Alias
18 from IPython.core.alias import AliasError, Alias
19 from IPython.core.error import UsageError
19 from IPython.core.error import UsageError
20 from IPython.core.magic import (
20 from IPython.core.magic import (
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
22 )
22 )
23 from IPython.testing.skipdoctest import skip_doctest
23 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.utils.openpy import source_to_unicode
24 from IPython.utils.openpy import source_to_unicode
25 from IPython.utils.process import abbrev_cwd
25 from IPython.utils.process import abbrev_cwd
26 from IPython.utils.terminal import set_term_title
26 from IPython.utils.terminal import set_term_title
27
27
28
28
29 @magics_class
29 @magics_class
30 class OSMagics(Magics):
30 class OSMagics(Magics):
31 """Magics to interact with the underlying OS (shell-type functionality).
31 """Magics to interact with the underlying OS (shell-type functionality).
32 """
32 """
33
33
34 @skip_doctest
34 @skip_doctest
35 @line_magic
35 @line_magic
36 def alias(self, parameter_s=''):
36 def alias(self, parameter_s=''):
37 """Define an alias for a system command.
37 """Define an alias for a system command.
38
38
39 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
39 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
40
40
41 Then, typing 'alias_name params' will execute the system command 'cmd
41 Then, typing 'alias_name params' will execute the system command 'cmd
42 params' (from your underlying operating system).
42 params' (from your underlying operating system).
43
43
44 Aliases have lower precedence than magic functions and Python normal
44 Aliases have lower precedence than magic functions and Python normal
45 variables, so if 'foo' is both a Python variable and an alias, the
45 variables, so if 'foo' is both a Python variable and an alias, the
46 alias can not be executed until 'del foo' removes the Python variable.
46 alias can not be executed until 'del foo' removes the Python variable.
47
47
48 You can use the %l specifier in an alias definition to represent the
48 You can use the %l specifier in an alias definition to represent the
49 whole line when the alias is called. For example::
49 whole line when the alias is called. For example::
50
50
51 In [2]: alias bracket echo "Input in brackets: <%l>"
51 In [2]: alias bracket echo "Input in brackets: <%l>"
52 In [3]: bracket hello world
52 In [3]: bracket hello world
53 Input in brackets: <hello world>
53 Input in brackets: <hello world>
54
54
55 You can also define aliases with parameters using %s specifiers (one
55 You can also define aliases with parameters using %s specifiers (one
56 per parameter)::
56 per parameter)::
57
57
58 In [1]: alias parts echo first %s second %s
58 In [1]: alias parts echo first %s second %s
59 In [2]: %parts A B
59 In [2]: %parts A B
60 first A second B
60 first A second B
61 In [3]: %parts A
61 In [3]: %parts A
62 Incorrect number of arguments: 2 expected.
62 Incorrect number of arguments: 2 expected.
63 parts is an alias to: 'echo first %s second %s'
63 parts is an alias to: 'echo first %s second %s'
64
64
65 Note that %l and %s are mutually exclusive. You can only use one or
65 Note that %l and %s are mutually exclusive. You can only use one or
66 the other in your aliases.
66 the other in your aliases.
67
67
68 Aliases expand Python variables just like system calls using ! or !!
68 Aliases expand Python variables just like system calls using ! or !!
69 do: all expressions prefixed with '$' get expanded. For details of
69 do: all expressions prefixed with '$' get expanded. For details of
70 the semantic rules, see PEP-215:
70 the semantic rules, see PEP-215:
71 http://www.python.org/peps/pep-0215.html. This is the library used by
71 http://www.python.org/peps/pep-0215.html. This is the library used by
72 IPython for variable expansion. If you want to access a true shell
72 IPython for variable expansion. If you want to access a true shell
73 variable, an extra $ is necessary to prevent its expansion by
73 variable, an extra $ is necessary to prevent its expansion by
74 IPython::
74 IPython::
75
75
76 In [6]: alias show echo
76 In [6]: alias show echo
77 In [7]: PATH='A Python string'
77 In [7]: PATH='A Python string'
78 In [8]: show $PATH
78 In [8]: show $PATH
79 A Python string
79 A Python string
80 In [9]: show $$PATH
80 In [9]: show $$PATH
81 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
81 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
82
82
83 You can use the alias facility to access all of $PATH. See the %rehashx
83 You can use the alias facility to access all of $PATH. See the %rehashx
84 function, which automatically creates aliases for the contents of your
84 function, which automatically creates aliases for the contents of your
85 $PATH.
85 $PATH.
86
86
87 If called with no parameters, %alias prints the current alias table
87 If called with no parameters, %alias prints the current alias table
88 for your system. For posix systems, the default aliases are 'cat',
88 for your system. For posix systems, the default aliases are 'cat',
89 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
89 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
90 aliases are added. For windows-based systems, the default aliases are
90 aliases are added. For windows-based systems, the default aliases are
91 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
91 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
92
92
93 You can see the definition of alias by adding a question mark in the
93 You can see the definition of alias by adding a question mark in the
94 end::
94 end::
95
95
96 In [1]: cat?
96 In [1]: cat?
97 Repr: <alias cat for 'cat'>"""
97 Repr: <alias cat for 'cat'>"""
98
98
99 par = parameter_s.strip()
99 par = parameter_s.strip()
100 if not par:
100 if not par:
101 aliases = sorted(self.shell.alias_manager.aliases)
101 aliases = sorted(self.shell.alias_manager.aliases)
102 # stored = self.shell.db.get('stored_aliases', {} )
102 # stored = self.shell.db.get('stored_aliases', {} )
103 # for k, v in stored:
103 # for k, v in stored:
104 # atab.append(k, v[0])
104 # atab.append(k, v[0])
105
105
106 print("Total number of aliases:", len(aliases))
106 print("Total number of aliases:", len(aliases))
107 sys.stdout.flush()
107 sys.stdout.flush()
108 return aliases
108 return aliases
109
109
110 # Now try to define a new one
110 # Now try to define a new one
111 try:
111 try:
112 alias,cmd = par.split(None, 1)
112 alias,cmd = par.split(None, 1)
113 except TypeError:
113 except TypeError:
114 print(oinspect.getdoc(self.alias))
114 print(oinspect.getdoc(self.alias))
115 return
115 return
116
116
117 try:
117 try:
118 self.shell.alias_manager.define_alias(alias, cmd)
118 self.shell.alias_manager.define_alias(alias, cmd)
119 except AliasError as e:
119 except AliasError as e:
120 print(e)
120 print(e)
121 # end magic_alias
121 # end magic_alias
122
122
123 @line_magic
123 @line_magic
124 def unalias(self, parameter_s=''):
124 def unalias(self, parameter_s=''):
125 """Remove an alias"""
125 """Remove an alias"""
126
126
127 aname = parameter_s.strip()
127 aname = parameter_s.strip()
128 try:
128 try:
129 self.shell.alias_manager.undefine_alias(aname)
129 self.shell.alias_manager.undefine_alias(aname)
130 except ValueError as e:
130 except ValueError as e:
131 print(e)
131 print(e)
132 return
132 return
133
133
134 stored = self.shell.db.get('stored_aliases', {} )
134 stored = self.shell.db.get('stored_aliases', {} )
135 if aname in stored:
135 if aname in stored:
136 print("Removing %stored alias",aname)
136 print("Removing %stored alias",aname)
137 del stored[aname]
137 del stored[aname]
138 self.shell.db['stored_aliases'] = stored
138 self.shell.db['stored_aliases'] = stored
139
139
140 @line_magic
140 @line_magic
141 def rehashx(self, parameter_s=''):
141 def rehashx(self, parameter_s=''):
142 """Update the alias table with all executable files in $PATH.
142 """Update the alias table with all executable files in $PATH.
143
143
144 rehashx explicitly checks that every entry in $PATH is a file
144 rehashx explicitly checks that every entry in $PATH is a file
145 with execute access (os.X_OK).
145 with execute access (os.X_OK).
146
146
147 Under Windows, it checks executability as a match against a
147 Under Windows, it checks executability as a match against a
148 '|'-separated string of extensions, stored in the IPython config
148 '|'-separated string of extensions, stored in the IPython config
149 variable win_exec_ext. This defaults to 'exe|com|bat'.
149 variable win_exec_ext. This defaults to 'exe|com|bat'.
150
150
151 This function also resets the root module cache of module completer,
151 This function also resets the root module cache of module completer,
152 used on slow filesystems.
152 used on slow filesystems.
153 """
153 """
154 from IPython.core.alias import InvalidAliasError
154 from IPython.core.alias import InvalidAliasError
155
155
156 # for the benefit of module completer in ipy_completers.py
156 # for the benefit of module completer in ipy_completers.py
157 del self.shell.db['rootmodules_cache']
157 del self.shell.db['rootmodules_cache']
158
158
159 path = [os.path.abspath(os.path.expanduser(p)) for p in
159 path = [os.path.abspath(os.path.expanduser(p)) for p in
160 os.environ.get('PATH','').split(os.pathsep)]
160 os.environ.get('PATH','').split(os.pathsep)]
161
161
162 syscmdlist = []
162 syscmdlist = []
163 # Now define isexec in a cross platform manner.
163 # Now define isexec in a cross platform manner.
164 if os.name == 'posix':
164 if os.name == 'posix':
165 isexec = lambda fname:os.path.isfile(fname) and \
165 isexec = lambda fname:os.path.isfile(fname) and \
166 os.access(fname,os.X_OK)
166 os.access(fname,os.X_OK)
167 else:
167 else:
168 try:
168 try:
169 winext = os.environ['pathext'].replace(';','|').replace('.','')
169 winext = os.environ['pathext'].replace(';','|').replace('.','')
170 except KeyError:
170 except KeyError:
171 winext = 'exe|com|bat|py'
171 winext = 'exe|com|bat|py'
172 if 'py' not in winext:
172 if 'py' not in winext:
173 winext += '|py'
173 winext += '|py'
174 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
174 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
175 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
175 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
176 savedir = os.getcwd()
176 savedir = os.getcwd()
177
177
178 # Now walk the paths looking for executables to alias.
178 # Now walk the paths looking for executables to alias.
179 try:
179 try:
180 # write the whole loop for posix/Windows so we don't have an if in
180 # write the whole loop for posix/Windows so we don't have an if in
181 # the innermost part
181 # the innermost part
182 if os.name == 'posix':
182 if os.name == 'posix':
183 for pdir in path:
183 for pdir in path:
184 try:
184 try:
185 os.chdir(pdir)
185 os.chdir(pdir)
186 dirlist = os.listdir(pdir)
186 dirlist = os.listdir(pdir)
187 except OSError:
187 except OSError:
188 continue
188 continue
189 for ff in dirlist:
189 for ff in dirlist:
190 if isexec(ff):
190 if isexec(ff):
191 try:
191 try:
192 # Removes dots from the name since ipython
192 # Removes dots from the name since ipython
193 # will assume names with dots to be python.
193 # will assume names with dots to be python.
194 if not self.shell.alias_manager.is_alias(ff):
194 if not self.shell.alias_manager.is_alias(ff):
195 self.shell.alias_manager.define_alias(
195 self.shell.alias_manager.define_alias(
196 ff.replace('.',''), ff)
196 ff.replace('.',''), ff)
197 except InvalidAliasError:
197 except InvalidAliasError:
198 pass
198 pass
199 else:
199 else:
200 syscmdlist.append(ff)
200 syscmdlist.append(ff)
201 else:
201 else:
202 no_alias = Alias.blacklist
202 no_alias = Alias.blacklist
203 for pdir in path:
203 for pdir in path:
204 try:
204 try:
205 os.chdir(pdir)
205 os.chdir(pdir)
206 dirlist = os.listdir(pdir)
206 dirlist = os.listdir(pdir)
207 except OSError:
207 except OSError:
208 continue
208 continue
209 for ff in dirlist:
209 for ff in dirlist:
210 base, ext = os.path.splitext(ff)
210 base, ext = os.path.splitext(ff)
211 if isexec(ff) and base.lower() not in no_alias:
211 if isexec(ff) and base.lower() not in no_alias:
212 if ext.lower() == '.exe':
212 if ext.lower() == '.exe':
213 ff = base
213 ff = base
214 try:
214 try:
215 # Removes dots from the name since ipython
215 # Removes dots from the name since ipython
216 # will assume names with dots to be python.
216 # will assume names with dots to be python.
217 self.shell.alias_manager.define_alias(
217 self.shell.alias_manager.define_alias(
218 base.lower().replace('.',''), ff)
218 base.lower().replace('.',''), ff)
219 except InvalidAliasError:
219 except InvalidAliasError:
220 pass
220 pass
221 syscmdlist.append(ff)
221 syscmdlist.append(ff)
222 self.shell.db['syscmdlist'] = syscmdlist
222 self.shell.db['syscmdlist'] = syscmdlist
223 finally:
223 finally:
224 os.chdir(savedir)
224 os.chdir(savedir)
225
225
226 @skip_doctest
226 @skip_doctest
227 @line_magic
227 @line_magic
228 def pwd(self, parameter_s=''):
228 def pwd(self, parameter_s=''):
229 """Return the current working directory path.
229 """Return the current working directory path.
230
230
231 Examples
231 Examples
232 --------
232 --------
233 ::
233 ::
234
234
235 In [9]: pwd
235 In [9]: pwd
236 Out[9]: '/home/tsuser/sprint/ipython'
236 Out[9]: '/home/tsuser/sprint/ipython'
237 """
237 """
238 try:
238 try:
239 return os.getcwd()
239 return os.getcwd()
240 except FileNotFoundError:
240 except FileNotFoundError:
241 raise UsageError("CWD no longer exists - please use %cd to change directory.")
241 raise UsageError("CWD no longer exists - please use %cd to change directory.")
242
242
243 @skip_doctest
243 @skip_doctest
244 @line_magic
244 @line_magic
245 def cd(self, parameter_s=''):
245 def cd(self, parameter_s=''):
246 """Change the current working directory.
246 """Change the current working directory.
247
247
248 This command automatically maintains an internal list of directories
248 This command automatically maintains an internal list of directories
249 you visit during your IPython session, in the variable _dh. The
249 you visit during your IPython session, in the variable _dh. The
250 command %dhist shows this history nicely formatted. You can also
250 command %dhist shows this history nicely formatted. You can also
251 do 'cd -<tab>' to see directory history conveniently.
251 do 'cd -<tab>' to see directory history conveniently.
252
252
253 Usage:
253 Usage:
254
254
255 cd 'dir': changes to directory 'dir'.
255 cd 'dir': changes to directory 'dir'.
256
256
257 cd -: changes to the last visited directory.
257 cd -: changes to the last visited directory.
258
258
259 cd -<n>: changes to the n-th directory in the directory history.
259 cd -<n>: changes to the n-th directory in the directory history.
260
260
261 cd --foo: change to directory that matches 'foo' in history
261 cd --foo: change to directory that matches 'foo' in history
262
262
263 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
263 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
264 (note: cd <bookmark_name> is enough if there is no
264 (note: cd <bookmark_name> is enough if there is no
265 directory <bookmark_name>, but a bookmark with the name exists.)
265 directory <bookmark_name>, but a bookmark with the name exists.)
266 'cd -b <tab>' allows you to tab-complete bookmark names.
266 'cd -b <tab>' allows you to tab-complete bookmark names.
267
267
268 Options:
268 Options:
269
269
270 -q: quiet. Do not print the working directory after the cd command is
270 -q: quiet. Do not print the working directory after the cd command is
271 executed. By default IPython's cd command does print this directory,
271 executed. By default IPython's cd command does print this directory,
272 since the default prompts do not display path information.
272 since the default prompts do not display path information.
273
273
274 Note that !cd doesn't work for this purpose because the shell where
274 Note that !cd doesn't work for this purpose because the shell where
275 !command runs is immediately discarded after executing 'command'.
275 !command runs is immediately discarded after executing 'command'.
276
276
277 Examples
277 Examples
278 --------
278 --------
279 ::
279 ::
280
280
281 In [10]: cd parent/child
281 In [10]: cd parent/child
282 /home/tsuser/parent/child
282 /home/tsuser/parent/child
283 """
283 """
284
284
285 try:
285 try:
286 oldcwd = os.getcwd()
286 oldcwd = os.getcwd()
287 except FileNotFoundError:
287 except FileNotFoundError:
288 # Happens if the CWD has been deleted.
288 # Happens if the CWD has been deleted.
289 oldcwd = None
289 oldcwd = None
290
290
291 numcd = re.match(r'(-)(\d+)$',parameter_s)
291 numcd = re.match(r'(-)(\d+)$',parameter_s)
292 # jump in directory history by number
292 # jump in directory history by number
293 if numcd:
293 if numcd:
294 nn = int(numcd.group(2))
294 nn = int(numcd.group(2))
295 try:
295 try:
296 ps = self.shell.user_ns['_dh'][nn]
296 ps = self.shell.user_ns['_dh'][nn]
297 except IndexError:
297 except IndexError:
298 print('The requested directory does not exist in history.')
298 print('The requested directory does not exist in history.')
299 return
299 return
300 else:
300 else:
301 opts = {}
301 opts = {}
302 elif parameter_s.startswith('--'):
302 elif parameter_s.startswith('--'):
303 ps = None
303 ps = None
304 fallback = None
304 fallback = None
305 pat = parameter_s[2:]
305 pat = parameter_s[2:]
306 dh = self.shell.user_ns['_dh']
306 dh = self.shell.user_ns['_dh']
307 # first search only by basename (last component)
307 # first search only by basename (last component)
308 for ent in reversed(dh):
308 for ent in reversed(dh):
309 if pat in os.path.basename(ent) and os.path.isdir(ent):
309 if pat in os.path.basename(ent) and os.path.isdir(ent):
310 ps = ent
310 ps = ent
311 break
311 break
312
312
313 if fallback is None and pat in ent and os.path.isdir(ent):
313 if fallback is None and pat in ent and os.path.isdir(ent):
314 fallback = ent
314 fallback = ent
315
315
316 # if we have no last part match, pick the first full path match
316 # if we have no last part match, pick the first full path match
317 if ps is None:
317 if ps is None:
318 ps = fallback
318 ps = fallback
319
319
320 if ps is None:
320 if ps is None:
321 print("No matching entry in directory history")
321 print("No matching entry in directory history")
322 return
322 return
323 else:
323 else:
324 opts = {}
324 opts = {}
325
325
326
326
327 else:
327 else:
328 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
328 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
329 # jump to previous
329 # jump to previous
330 if ps == '-':
330 if ps == '-':
331 try:
331 try:
332 ps = self.shell.user_ns['_dh'][-2]
332 ps = self.shell.user_ns['_dh'][-2]
333 except IndexError:
333 except IndexError:
334 raise UsageError('%cd -: No previous directory to change to.')
334 raise UsageError('%cd -: No previous directory to change to.')
335 # jump to bookmark if needed
335 # jump to bookmark if needed
336 else:
336 else:
337 if not os.path.isdir(ps) or 'b' in opts:
337 if not os.path.isdir(ps) or 'b' in opts:
338 bkms = self.shell.db.get('bookmarks', {})
338 bkms = self.shell.db.get('bookmarks', {})
339
339
340 if ps in bkms:
340 if ps in bkms:
341 target = bkms[ps]
341 target = bkms[ps]
342 print('(bookmark:%s) -> %s' % (ps, target))
342 print('(bookmark:%s) -> %s' % (ps, target))
343 ps = target
343 ps = target
344 else:
344 else:
345 if 'b' in opts:
345 if 'b' in opts:
346 raise UsageError("Bookmark '%s' not found. "
346 raise UsageError("Bookmark '%s' not found. "
347 "Use '%%bookmark -l' to see your bookmarks." % ps)
347 "Use '%%bookmark -l' to see your bookmarks." % ps)
348
348
349 # at this point ps should point to the target dir
349 # at this point ps should point to the target dir
350 if ps:
350 if ps:
351 try:
351 try:
352 os.chdir(os.path.expanduser(ps))
352 os.chdir(os.path.expanduser(ps))
353 if hasattr(self.shell, 'term_title') and self.shell.term_title:
353 if hasattr(self.shell, 'term_title') and self.shell.term_title:
354 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
354 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
355 except OSError:
355 except OSError:
356 print(sys.exc_info()[1])
356 print(sys.exc_info()[1])
357 else:
357 else:
358 cwd = os.getcwd()
358 cwd = os.getcwd()
359 dhist = self.shell.user_ns['_dh']
359 dhist = self.shell.user_ns['_dh']
360 if oldcwd != cwd:
360 if oldcwd != cwd:
361 dhist.append(cwd)
361 dhist.append(cwd)
362 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
362 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
363
363
364 else:
364 else:
365 os.chdir(self.shell.home_dir)
365 os.chdir(self.shell.home_dir)
366 if hasattr(self.shell, 'term_title') and self.shell.term_title:
366 if hasattr(self.shell, 'term_title') and self.shell.term_title:
367 set_term_title(self.shell.term_title_format.format(cwd="~"))
367 set_term_title(self.shell.term_title_format.format(cwd="~"))
368 cwd = os.getcwd()
368 cwd = os.getcwd()
369 dhist = self.shell.user_ns['_dh']
369 dhist = self.shell.user_ns['_dh']
370
370
371 if oldcwd != cwd:
371 if oldcwd != cwd:
372 dhist.append(cwd)
372 dhist.append(cwd)
373 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
373 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
374 if not 'q' in opts and self.shell.user_ns['_dh']:
374 if not 'q' in opts and self.shell.user_ns['_dh']:
375 print(self.shell.user_ns['_dh'][-1])
375 print(self.shell.user_ns['_dh'][-1])
376
376
377 @line_magic
377 @line_magic
378 def env(self, parameter_s=''):
378 def env(self, parameter_s=''):
379 """Get, set, or list environment variables.
379 """Get, set, or list environment variables.
380
380
381 Usage:\\
381 Usage:\\
382
382
383 %env: lists all environment variables/values
383 %env: lists all environment variables/values
384 %env var: get value for var
384 %env var: get value for var
385 %env var val: set value for var
385 %env var val: set value for var
386 %env var=val: set value for var
386 %env var=val: set value for var
387 %env var=$val: set value for var, using python expansion if possible
387 %env var=$val: set value for var, using python expansion if possible
388 """
388 """
389 if parameter_s.strip():
389 if parameter_s.strip():
390 split = '=' if '=' in parameter_s else ' '
390 split = '=' if '=' in parameter_s else ' '
391 bits = parameter_s.split(split)
391 bits = parameter_s.split(split)
392 if len(bits) == 1:
392 if len(bits) == 1:
393 key = parameter_s.strip()
393 key = parameter_s.strip()
394 if key in os.environ:
394 if key in os.environ:
395 return os.environ[key]
395 return os.environ[key]
396 else:
396 else:
397 err = "Environment does not have key: {0}".format(key)
397 err = "Environment does not have key: {0}".format(key)
398 raise UsageError(err)
398 raise UsageError(err)
399 if len(bits) > 1:
399 if len(bits) > 1:
400 return self.set_env(parameter_s)
400 return self.set_env(parameter_s)
401 return dict(os.environ)
401 return dict(os.environ)
402
402
403 @line_magic
403 @line_magic
404 def set_env(self, parameter_s):
404 def set_env(self, parameter_s):
405 """Set environment variables. Assumptions are that either "val" is a
405 """Set environment variables. Assumptions are that either "val" is a
406 name in the user namespace, or val is something that evaluates to a
406 name in the user namespace, or val is something that evaluates to a
407 string.
407 string.
408
408
409 Usage:\\
409 Usage:\\
410 %set_env var val: set value for var
410 %set_env var val: set value for var
411 %set_env var=val: set value for var
411 %set_env var=val: set value for var
412 %set_env var=$val: set value for var, using python expansion if possible
412 %set_env var=$val: set value for var, using python expansion if possible
413 """
413 """
414 split = '=' if '=' in parameter_s else ' '
414 split = '=' if '=' in parameter_s else ' '
415 bits = parameter_s.split(split, 1)
415 bits = parameter_s.split(split, 1)
416 if not parameter_s.strip() or len(bits)<2:
416 if not parameter_s.strip() or len(bits)<2:
417 raise UsageError("usage is 'set_env var=val'")
417 raise UsageError("usage is 'set_env var=val'")
418 var = bits[0].strip()
418 var = bits[0].strip()
419 val = bits[1].strip()
419 val = bits[1].strip()
420 if re.match(r'.*\s.*', var):
420 if re.match(r'.*\s.*', var):
421 # an environment variable with whitespace is almost certainly
421 # an environment variable with whitespace is almost certainly
422 # not what the user intended. what's more likely is the wrong
422 # not what the user intended. what's more likely is the wrong
423 # split was chosen, ie for "set_env cmd_args A=B", we chose
423 # split was chosen, ie for "set_env cmd_args A=B", we chose
424 # '=' for the split and should have chosen ' '. to get around
424 # '=' for the split and should have chosen ' '. to get around
425 # this, users should just assign directly to os.environ or use
425 # this, users should just assign directly to os.environ or use
426 # standard magic {var} expansion.
426 # standard magic {var} expansion.
427 err = "refusing to set env var with whitespace: '{0}'"
427 err = "refusing to set env var with whitespace: '{0}'"
428 err = err.format(val)
428 err = err.format(val)
429 raise UsageError(err)
429 raise UsageError(err)
430 os.environ[var] = val
430 os.environ[var] = val
431 print('env: {0}={1}'.format(var,val))
431 print('env: {0}={1}'.format(var,val))
432
432
433 @line_magic
433 @line_magic
434 def pushd(self, parameter_s=''):
434 def pushd(self, parameter_s=''):
435 """Place the current dir on stack and change directory.
435 """Place the current dir on stack and change directory.
436
436
437 Usage:\\
437 Usage:\\
438 %pushd ['dirname']
438 %pushd ['dirname']
439 """
439 """
440
440
441 dir_s = self.shell.dir_stack
441 dir_s = self.shell.dir_stack
442 tgt = os.path.expanduser(parameter_s)
442 tgt = os.path.expanduser(parameter_s)
443 cwd = os.getcwd().replace(self.shell.home_dir,'~')
443 cwd = os.getcwd().replace(self.shell.home_dir,'~')
444 if tgt:
444 if tgt:
445 self.cd(parameter_s)
445 self.cd(parameter_s)
446 dir_s.insert(0,cwd)
446 dir_s.insert(0,cwd)
447 return self.shell.magic('dirs')
447 return self.shell.magic('dirs')
448
448
449 @line_magic
449 @line_magic
450 def popd(self, parameter_s=''):
450 def popd(self, parameter_s=''):
451 """Change to directory popped off the top of the stack.
451 """Change to directory popped off the top of the stack.
452 """
452 """
453 if not self.shell.dir_stack:
453 if not self.shell.dir_stack:
454 raise UsageError("%popd on empty stack")
454 raise UsageError("%popd on empty stack")
455 top = self.shell.dir_stack.pop(0)
455 top = self.shell.dir_stack.pop(0)
456 self.cd(top)
456 self.cd(top)
457 print("popd ->",top)
457 print("popd ->",top)
458
458
459 @line_magic
459 @line_magic
460 def dirs(self, parameter_s=''):
460 def dirs(self, parameter_s=''):
461 """Return the current directory stack."""
461 """Return the current directory stack."""
462
462
463 return self.shell.dir_stack
463 return self.shell.dir_stack
464
464
465 @line_magic
465 @line_magic
466 def dhist(self, parameter_s=''):
466 def dhist(self, parameter_s=''):
467 """Print your history of visited directories.
467 """Print your history of visited directories.
468
468
469 %dhist -> print full history\\
469 %dhist -> print full history\\
470 %dhist n -> print last n entries only\\
470 %dhist n -> print last n entries only\\
471 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
471 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
472
472
473 This history is automatically maintained by the %cd command, and
473 This history is automatically maintained by the %cd command, and
474 always available as the global list variable _dh. You can use %cd -<n>
474 always available as the global list variable _dh. You can use %cd -<n>
475 to go to directory number <n>.
475 to go to directory number <n>.
476
476
477 Note that most of time, you should view directory history by entering
477 Note that most of time, you should view directory history by entering
478 cd -<TAB>.
478 cd -<TAB>.
479
479
480 """
480 """
481
481
482 dh = self.shell.user_ns['_dh']
482 dh = self.shell.user_ns['_dh']
483 if parameter_s:
483 if parameter_s:
484 try:
484 try:
485 args = map(int,parameter_s.split())
485 args = map(int,parameter_s.split())
486 except:
486 except:
487 self.arg_err(self.dhist)
487 self.arg_err(self.dhist)
488 return
488 return
489 if len(args) == 1:
489 if len(args) == 1:
490 ini,fin = max(len(dh)-(args[0]),0),len(dh)
490 ini,fin = max(len(dh)-(args[0]),0),len(dh)
491 elif len(args) == 2:
491 elif len(args) == 2:
492 ini,fin = args
492 ini,fin = args
493 fin = min(fin, len(dh))
493 fin = min(fin, len(dh))
494 else:
494 else:
495 self.arg_err(self.dhist)
495 self.arg_err(self.dhist)
496 return
496 return
497 else:
497 else:
498 ini,fin = 0,len(dh)
498 ini,fin = 0,len(dh)
499 print('Directory history (kept in _dh)')
499 print('Directory history (kept in _dh)')
500 for i in range(ini, fin):
500 for i in range(ini, fin):
501 print("%d: %s" % (i, dh[i]))
501 print("%d: %s" % (i, dh[i]))
502
502
503 @skip_doctest
503 @skip_doctest
504 @line_magic
504 @line_magic
505 def sc(self, parameter_s=''):
505 def sc(self, parameter_s=''):
506 """Shell capture - run shell command and capture output (DEPRECATED use !).
506 """Shell capture - run shell command and capture output (DEPRECATED use !).
507
507
508 DEPRECATED. Suboptimal, retained for backwards compatibility.
508 DEPRECATED. Suboptimal, retained for backwards compatibility.
509
509
510 You should use the form 'var = !command' instead. Example:
510 You should use the form 'var = !command' instead. Example:
511
511
512 "%sc -l myfiles = ls ~" should now be written as
512 "%sc -l myfiles = ls ~" should now be written as
513
513
514 "myfiles = !ls ~"
514 "myfiles = !ls ~"
515
515
516 myfiles.s, myfiles.l and myfiles.n still apply as documented
516 myfiles.s, myfiles.l and myfiles.n still apply as documented
517 below.
517 below.
518
518
519 --
519 --
520 %sc [options] varname=command
520 %sc [options] varname=command
521
521
522 IPython will run the given command using commands.getoutput(), and
522 IPython will run the given command using commands.getoutput(), and
523 will then update the user's interactive namespace with a variable
523 will then update the user's interactive namespace with a variable
524 called varname, containing the value of the call. Your command can
524 called varname, containing the value of the call. Your command can
525 contain shell wildcards, pipes, etc.
525 contain shell wildcards, pipes, etc.
526
526
527 The '=' sign in the syntax is mandatory, and the variable name you
527 The '=' sign in the syntax is mandatory, and the variable name you
528 supply must follow Python's standard conventions for valid names.
528 supply must follow Python's standard conventions for valid names.
529
529
530 (A special format without variable name exists for internal use)
530 (A special format without variable name exists for internal use)
531
531
532 Options:
532 Options:
533
533
534 -l: list output. Split the output on newlines into a list before
534 -l: list output. Split the output on newlines into a list before
535 assigning it to the given variable. By default the output is stored
535 assigning it to the given variable. By default the output is stored
536 as a single string.
536 as a single string.
537
537
538 -v: verbose. Print the contents of the variable.
538 -v: verbose. Print the contents of the variable.
539
539
540 In most cases you should not need to split as a list, because the
540 In most cases you should not need to split as a list, because the
541 returned value is a special type of string which can automatically
541 returned value is a special type of string which can automatically
542 provide its contents either as a list (split on newlines) or as a
542 provide its contents either as a list (split on newlines) or as a
543 space-separated string. These are convenient, respectively, either
543 space-separated string. These are convenient, respectively, either
544 for sequential processing or to be passed to a shell command.
544 for sequential processing or to be passed to a shell command.
545
545
546 For example::
546 For example::
547
547
548 # Capture into variable a
548 # Capture into variable a
549 In [1]: sc a=ls *py
549 In [1]: sc a=ls *py
550
550
551 # a is a string with embedded newlines
551 # a is a string with embedded newlines
552 In [2]: a
552 In [2]: a
553 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
553 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
554
554
555 # which can be seen as a list:
555 # which can be seen as a list:
556 In [3]: a.l
556 In [3]: a.l
557 Out[3]: ['setup.py', 'win32_manual_post_install.py']
557 Out[3]: ['setup.py', 'win32_manual_post_install.py']
558
558
559 # or as a whitespace-separated string:
559 # or as a whitespace-separated string:
560 In [4]: a.s
560 In [4]: a.s
561 Out[4]: 'setup.py win32_manual_post_install.py'
561 Out[4]: 'setup.py win32_manual_post_install.py'
562
562
563 # a.s is useful to pass as a single command line:
563 # a.s is useful to pass as a single command line:
564 In [5]: !wc -l $a.s
564 In [5]: !wc -l $a.s
565 146 setup.py
565 146 setup.py
566 130 win32_manual_post_install.py
566 130 win32_manual_post_install.py
567 276 total
567 276 total
568
568
569 # while the list form is useful to loop over:
569 # while the list form is useful to loop over:
570 In [6]: for f in a.l:
570 In [6]: for f in a.l:
571 ...: !wc -l $f
571 ...: !wc -l $f
572 ...:
572 ...:
573 146 setup.py
573 146 setup.py
574 130 win32_manual_post_install.py
574 130 win32_manual_post_install.py
575
575
576 Similarly, the lists returned by the -l option are also special, in
576 Similarly, the lists returned by the -l option are also special, in
577 the sense that you can equally invoke the .s attribute on them to
577 the sense that you can equally invoke the .s attribute on them to
578 automatically get a whitespace-separated string from their contents::
578 automatically get a whitespace-separated string from their contents::
579
579
580 In [7]: sc -l b=ls *py
580 In [7]: sc -l b=ls *py
581
581
582 In [8]: b
582 In [8]: b
583 Out[8]: ['setup.py', 'win32_manual_post_install.py']
583 Out[8]: ['setup.py', 'win32_manual_post_install.py']
584
584
585 In [9]: b.s
585 In [9]: b.s
586 Out[9]: 'setup.py win32_manual_post_install.py'
586 Out[9]: 'setup.py win32_manual_post_install.py'
587
587
588 In summary, both the lists and strings used for output capture have
588 In summary, both the lists and strings used for output capture have
589 the following special attributes::
589 the following special attributes::
590
590
591 .l (or .list) : value as list.
591 .l (or .list) : value as list.
592 .n (or .nlstr): value as newline-separated string.
592 .n (or .nlstr): value as newline-separated string.
593 .s (or .spstr): value as space-separated string.
593 .s (or .spstr): value as space-separated string.
594 """
594 """
595
595
596 opts,args = self.parse_options(parameter_s, 'lv')
596 opts,args = self.parse_options(parameter_s, 'lv')
597 # Try to get a variable name and command to run
597 # Try to get a variable name and command to run
598 try:
598 try:
599 # the variable name must be obtained from the parse_options
599 # the variable name must be obtained from the parse_options
600 # output, which uses shlex.split to strip options out.
600 # output, which uses shlex.split to strip options out.
601 var,_ = args.split('=', 1)
601 var,_ = args.split('=', 1)
602 var = var.strip()
602 var = var.strip()
603 # But the command has to be extracted from the original input
603 # But the command has to be extracted from the original input
604 # parameter_s, not on what parse_options returns, to avoid the
604 # parameter_s, not on what parse_options returns, to avoid the
605 # quote stripping which shlex.split performs on it.
605 # quote stripping which shlex.split performs on it.
606 _,cmd = parameter_s.split('=', 1)
606 _,cmd = parameter_s.split('=', 1)
607 except ValueError:
607 except ValueError:
608 var,cmd = '',''
608 var,cmd = '',''
609 # If all looks ok, proceed
609 # If all looks ok, proceed
610 split = 'l' in opts
610 split = 'l' in opts
611 out = self.shell.getoutput(cmd, split=split)
611 out = self.shell.getoutput(cmd, split=split)
612 if 'v' in opts:
612 if 'v' in opts:
613 print('%s ==\n%s' % (var, pformat(out)))
613 print('%s ==\n%s' % (var, pformat(out)))
614 if var:
614 if var:
615 self.shell.user_ns.update({var:out})
615 self.shell.user_ns.update({var:out})
616 else:
616 else:
617 return out
617 return out
618
618
619 @line_cell_magic
619 @line_cell_magic
620 def sx(self, line='', cell=None):
620 def sx(self, line='', cell=None):
621 """Shell execute - run shell command and capture output (!! is short-hand).
621 """Shell execute - run shell command and capture output (!! is short-hand).
622
622
623 %sx command
623 %sx command
624
624
625 IPython will run the given command using commands.getoutput(), and
625 IPython will run the given command using commands.getoutput(), and
626 return the result formatted as a list (split on '\\n'). Since the
626 return the result formatted as a list (split on '\\n'). Since the
627 output is _returned_, it will be stored in ipython's regular output
627 output is _returned_, it will be stored in ipython's regular output
628 cache Out[N] and in the '_N' automatic variables.
628 cache Out[N] and in the '_N' automatic variables.
629
629
630 Notes:
630 Notes:
631
631
632 1) If an input line begins with '!!', then %sx is automatically
632 1) If an input line begins with '!!', then %sx is automatically
633 invoked. That is, while::
633 invoked. That is, while::
634
634
635 !ls
635 !ls
636
636
637 causes ipython to simply issue system('ls'), typing::
637 causes ipython to simply issue system('ls'), typing::
638
638
639 !!ls
639 !!ls
640
640
641 is a shorthand equivalent to::
641 is a shorthand equivalent to::
642
642
643 %sx ls
643 %sx ls
644
644
645 2) %sx differs from %sc in that %sx automatically splits into a list,
645 2) %sx differs from %sc in that %sx automatically splits into a list,
646 like '%sc -l'. The reason for this is to make it as easy as possible
646 like '%sc -l'. The reason for this is to make it as easy as possible
647 to process line-oriented shell output via further python commands.
647 to process line-oriented shell output via further python commands.
648 %sc is meant to provide much finer control, but requires more
648 %sc is meant to provide much finer control, but requires more
649 typing.
649 typing.
650
650
651 3) Just like %sc -l, this is a list with special attributes:
651 3) Just like %sc -l, this is a list with special attributes:
652 ::
652 ::
653
653
654 .l (or .list) : value as list.
654 .l (or .list) : value as list.
655 .n (or .nlstr): value as newline-separated string.
655 .n (or .nlstr): value as newline-separated string.
656 .s (or .spstr): value as whitespace-separated string.
656 .s (or .spstr): value as whitespace-separated string.
657
657
658 This is very useful when trying to use such lists as arguments to
658 This is very useful when trying to use such lists as arguments to
659 system commands."""
659 system commands."""
660
660
661 if cell is None:
661 if cell is None:
662 # line magic
662 # line magic
663 return self.shell.getoutput(line)
663 return self.shell.getoutput(line)
664 else:
664 else:
665 opts,args = self.parse_options(line, '', 'out=')
665 opts,args = self.parse_options(line, '', 'out=')
666 output = self.shell.getoutput(cell)
666 output = self.shell.getoutput(cell)
667 out_name = opts.get('out', opts.get('o'))
667 out_name = opts.get('out', opts.get('o'))
668 if out_name:
668 if out_name:
669 self.shell.user_ns[out_name] = output
669 self.shell.user_ns[out_name] = output
670 else:
670 else:
671 return output
671 return output
672
672
673 system = line_cell_magic('system')(sx)
673 system = line_cell_magic('system')(sx)
674 bang = cell_magic('!')(sx)
674 bang = cell_magic('!')(sx)
675
675
676 @line_magic
676 @line_magic
677 def bookmark(self, parameter_s=''):
677 def bookmark(self, parameter_s=''):
678 """Manage IPython's bookmark system.
678 """Manage IPython's bookmark system.
679
679
680 %bookmark <name> - set bookmark to current dir
680 %bookmark <name> - set bookmark to current dir
681 %bookmark <name> <dir> - set bookmark to <dir>
681 %bookmark <name> <dir> - set bookmark to <dir>
682 %bookmark -l - list all bookmarks
682 %bookmark -l - list all bookmarks
683 %bookmark -d <name> - remove bookmark
683 %bookmark -d <name> - remove bookmark
684 %bookmark -r - remove all bookmarks
684 %bookmark -r - remove all bookmarks
685
685
686 You can later on access a bookmarked folder with::
686 You can later on access a bookmarked folder with::
687
687
688 %cd -b <name>
688 %cd -b <name>
689
689
690 or simply '%cd <name>' if there is no directory called <name> AND
690 or simply '%cd <name>' if there is no directory called <name> AND
691 there is such a bookmark defined.
691 there is such a bookmark defined.
692
692
693 Your bookmarks persist through IPython sessions, but they are
693 Your bookmarks persist through IPython sessions, but they are
694 associated with each profile."""
694 associated with each profile."""
695
695
696 opts,args = self.parse_options(parameter_s,'drl',mode='list')
696 opts,args = self.parse_options(parameter_s,'drl',mode='list')
697 if len(args) > 2:
697 if len(args) > 2:
698 raise UsageError("%bookmark: too many arguments")
698 raise UsageError("%bookmark: too many arguments")
699
699
700 bkms = self.shell.db.get('bookmarks',{})
700 bkms = self.shell.db.get('bookmarks',{})
701
701
702 if 'd' in opts:
702 if 'd' in opts:
703 try:
703 try:
704 todel = args[0]
704 todel = args[0]
705 except IndexError:
705 except IndexError:
706 raise UsageError(
706 raise UsageError(
707 "%bookmark -d: must provide a bookmark to delete")
707 "%bookmark -d: must provide a bookmark to delete")
708 else:
708 else:
709 try:
709 try:
710 del bkms[todel]
710 del bkms[todel]
711 except KeyError:
711 except KeyError:
712 raise UsageError(
712 raise UsageError(
713 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
713 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
714
714
715 elif 'r' in opts:
715 elif 'r' in opts:
716 bkms = {}
716 bkms = {}
717 elif 'l' in opts:
717 elif 'l' in opts:
718 bks = sorted(bkms)
718 bks = sorted(bkms)
719 if bks:
719 if bks:
720 size = max(map(len, bks))
720 size = max(map(len, bks))
721 else:
721 else:
722 size = 0
722 size = 0
723 fmt = '%-'+str(size)+'s -> %s'
723 fmt = '%-'+str(size)+'s -> %s'
724 print('Current bookmarks:')
724 print('Current bookmarks:')
725 for bk in bks:
725 for bk in bks:
726 print(fmt % (bk, bkms[bk]))
726 print(fmt % (bk, bkms[bk]))
727 else:
727 else:
728 if not args:
728 if not args:
729 raise UsageError("%bookmark: You must specify the bookmark name")
729 raise UsageError("%bookmark: You must specify the bookmark name")
730 elif len(args)==1:
730 elif len(args)==1:
731 bkms[args[0]] = os.getcwd()
731 bkms[args[0]] = os.getcwd()
732 elif len(args)==2:
732 elif len(args)==2:
733 bkms[args[0]] = args[1]
733 bkms[args[0]] = args[1]
734 self.shell.db['bookmarks'] = bkms
734 self.shell.db['bookmarks'] = bkms
735
735
736 @line_magic
736 @line_magic
737 def pycat(self, parameter_s=''):
737 def pycat(self, parameter_s=''):
738 """Show a syntax-highlighted file through a pager.
738 """Show a syntax-highlighted file through a pager.
739
739
740 This magic is similar to the cat utility, but it will assume the file
740 This magic is similar to the cat utility, but it will assume the file
741 to be Python source and will show it with syntax highlighting.
741 to be Python source and will show it with syntax highlighting.
742
742
743 This magic command can either take a local filename, an url,
743 This magic command can either take a local filename, an url,
744 an history range (see %history) or a macro as argument ::
744 an history range (see %history) or a macro as argument ::
745
745
746 %pycat myscript.py
746 %pycat myscript.py
747 %pycat 7-27
747 %pycat 7-27
748 %pycat myMacro
748 %pycat myMacro
749 %pycat http://www.example.com/myscript.py
749 %pycat http://www.example.com/myscript.py
750 """
750 """
751 if not parameter_s:
751 if not parameter_s:
752 raise UsageError('Missing filename, URL, input history range, '
752 raise UsageError('Missing filename, URL, input history range, '
753 'or macro.')
753 'or macro.')
754
754
755 try :
755 try :
756 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
756 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
757 except (ValueError, IOError):
757 except (ValueError, IOError):
758 print("Error: no such file, variable, URL, history range or macro")
758 print("Error: no such file, variable, URL, history range or macro")
759 return
759 return
760
760
761 page.page(self.shell.pycolorize(source_to_unicode(cont)))
761 page.page(self.shell.pycolorize(source_to_unicode(cont)))
762
762
763 @magic_arguments.magic_arguments()
763 @magic_arguments.magic_arguments()
764 @magic_arguments.argument(
764 @magic_arguments.argument(
765 '-a', '--append', action='store_true', default=False,
765 '-a', '--append', action='store_true', default=False,
766 help='Append contents of the cell to an existing file. '
766 help='Append contents of the cell to an existing file. '
767 'The file will be created if it does not exist.'
767 'The file will be created if it does not exist.'
768 )
768 )
769 @magic_arguments.argument(
769 @magic_arguments.argument(
770 'filename', type=str,
770 'filename', type=str,
771 help='file to write'
771 help='file to write'
772 )
772 )
773 @cell_magic
773 @cell_magic
774 def writefile(self, line, cell):
774 def writefile(self, line, cell):
775 """Write the contents of the cell to a file.
775 """Write the contents of the cell to a file.
776
776
777 The file will be overwritten unless the -a (--append) flag is specified.
777 The file will be overwritten unless the -a (--append) flag is specified.
778 """
778 """
779 line = line if len(line.split())==1 else '"%s"' % line
779 line = line if len(line.split())==1 else '"%s"' % line.strip("\"\'")
780 args = magic_arguments.parse_argstring(self.writefile, line)
780 args = magic_arguments.parse_argstring(self.writefile, line)
781 filename = os.path.expanduser(args.filename.strip("\"\'"))
781 filename = os.path.expanduser(args.filename.strip("\"\'"))
782
782
783 if os.path.exists(filename):
783 if os.path.exists(filename):
784 if args.append:
784 if args.append:
785 print("Appending to %s" % filename)
785 print("Appending to %s" % filename)
786 else:
786 else:
787 print("Overwriting %s" % filename)
787 print("Overwriting %s" % filename)
788 else:
788 else:
789 print("Writing %s" % filename)
789 print("Writing %s" % filename)
790
790
791 mode = 'a' if args.append else 'w'
791 mode = 'a' if args.append else 'w'
792 with io.open(filename, mode, encoding='utf-8') as f:
792 with io.open(filename, mode, encoding='utf-8') as f:
793 f.write(cell)
793 f.write(cell)
General Comments 0
You need to be logged in to leave comments. Login now