##// END OF EJS Templates
mglob to use _ip.load()
vivainio -
Show More
@@ -1,206 +1,205 b''
1 1 """Shell mode for IPython.
2 2
3 3 Start ipython in shell mode by invoking "ipython -p sh"
4 4
5 5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 6 shell mode and is recommended for users who don't care about pysh-mode
7 7 compatibility)
8 8 """
9 9
10 10 from IPython import ipapi
11 11 import os,textwrap
12 12
13 13 # The import below effectively obsoletes your old-style ipythonrc[.ini],
14 14 # so consider yourself warned!
15 15
16 16 import ipy_defaults
17 17
18 18 def main():
19 19 ip = ipapi.get()
20 20 o = ip.options
21 21 # autocall to "full" mode (smart mode is default, I like full mode)
22 22
23 23 o.autocall = 2
24 24
25 25 # Jason Orendorff's path class is handy to have in user namespace
26 26 # if you are doing shell-like stuff
27 27 try:
28 28 ip.ex("from path import path" )
29 29 except ImportError:
30 30 pass
31 31
32 32 # beefed up %env is handy in shell mode
33 33 import envpersist
34 34 import ipy_which
35 35 import ipy_app_completers
36 36 import ipy_rehashdir
37 37 import ipy_signals
38 38
39 39
40 40 ip.ex('import os')
41 41 ip.ex("def up(): os.chdir('..')")
42 42
43 43 # Nice prompt
44 44
45 45 o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
46 46 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
47 47 o.prompt_out= '<\#> '
48 48
49 49 from IPython import Release
50 50
51 51 import sys
52 52 # I like my banner minimal.
53 53 o.banner = "IPython %s [on Py %s]\n" % (Release.version,sys.version.split(None,1)[0])
54 54
55 55 # make 'd' an alias for ls -F
56 56
57 ip.magic('alias d ls -F --color=auto')
57 # ip.magic('alias d ls -F --color=auto')
58 58
59 59 ip.IP.default_option('cd','-q')
60 60
61 61 # If you only rarely want to execute the things you %edit...
62 62
63 63 #ip.IP.default_option('edit','-x')
64 64
65 65
66 66 o.prompts_pad_left="1"
67 67 # Remove all blank lines in between prompts, like a normal shell.
68 68 o.separate_in="0"
69 69 o.separate_out="0"
70 70 o.separate_out2="0"
71 71
72 72 # now alias all syscommands
73 73
74 74 db = ip.db
75 75
76 76 syscmds = db.get("syscmdlist",[] )
77 77 if not syscmds:
78 78 print textwrap.dedent("""
79 79 System command list not initialized, probably the first run...
80 80 running %rehashx to refresh the command list. Run %rehashx
81 81 again to refresh command list (after installing new software etc.)
82 82 """)
83 83 ip.magic('rehashx')
84 84 syscmds = db.get("syscmdlist")
85 85
86 86 # locase aliases on win#2 only
87 87 if os.name == 'posix':
88 88 mapper = lambda s:s
89 89 else:
90 90 def mapper(s): return s.lower()
91 91
92 92 for cmd in syscmds:
93 93 #print "al",cmd
94 94 noext, ext = os.path.splitext(cmd)
95 95 ip.IP.alias_table[mapper(noext)] = (0,cmd)
96 96
97 97 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
98 import IPython.external.mglob
99 IPython.external.mglob.ipython_install()
98 ip.load("IPython.external.mglob")
100 99
101 100 extend_shell_behavior(ip)
102 101
103 102 # XXX You do not need to understand the next function!
104 103 # This should probably be moved out of profile
105 104
106 105 def extend_shell_behavior(ip):
107 106
108 107 # Instead of making signature a global variable tie it to IPSHELL.
109 108 # In future if it is required to distinguish between different
110 109 # shells we can assign a signature per shell basis
111 110 ip.IP.__sig__ = 0xa005
112 111 # mark the IPSHELL with this signature
113 112 ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
114 113
115 114 from IPython.Itpl import ItplNS
116 115 from IPython.genutils import shell
117 116 # utility to expand user variables via Itpl
118 117 # xxx do something sensible with depth?
119 118 ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
120 119 str(ItplNS(cmd.replace('#','\#'), ip.IP.user_ns, get_locals()))
121 120
122 121 def get_locals():
123 122 """ Substituting a variable through Itpl deep inside the IPSHELL stack
124 123 requires the knowledge of all the variables in scope upto the last
125 124 IPSHELL frame. This routine simply merges all the local variables
126 125 on the IPSHELL stack without worrying about their scope rules
127 126 """
128 127 import sys
129 128 # note lambda expression constitues a function call
130 129 # hence fno should be incremented by one
131 130 getsig = lambda fno: sys._getframe(fno+1).f_globals \
132 131 ['__builtins__'].__dict__['__sig__']
133 132 getlvars = lambda fno: sys._getframe(fno+1).f_locals
134 133 # trackback until we enter the IPSHELL
135 134 frame_no = 1
136 135 sig = ip.IP.__sig__
137 136 fsig = ~sig
138 137 while fsig != sig :
139 138 try:
140 139 fsig = getsig(frame_no)
141 140 except (AttributeError, KeyError):
142 141 frame_no += 1
143 142 except ValueError:
144 143 # stack is depleted
145 144 # call did not originate from IPSHELL
146 145 return {}
147 146 first_frame = frame_no
148 147 # walk further back until we exit from IPSHELL or deplete stack
149 148 try:
150 149 while(sig == getsig(frame_no+1)):
151 150 frame_no += 1
152 151 except (AttributeError, KeyError, ValueError):
153 152 pass
154 153 # merge the locals from top down hence overriding
155 154 # any re-definitions of variables, functions etc.
156 155 lvars = {}
157 156 for fno in range(frame_no, first_frame-1, -1):
158 157 lvars.update(getlvars(fno))
159 158 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
160 159 return lvars
161 160
162 161 def _runlines(lines):
163 162 """Run a string of one or more lines of source.
164 163
165 164 This method is capable of running a string containing multiple source
166 165 lines, as if they had been entered at the IPython prompt. Since it
167 166 exposes IPython's processing machinery, the given strings can contain
168 167 magic calls (%magic), special shell access (!cmd), etc."""
169 168
170 169 # We must start with a clean buffer, in case this is run from an
171 170 # interactive IPython session (via a magic, for example).
172 171 ip.IP.resetbuffer()
173 172 lines = lines.split('\n')
174 173 more = 0
175 174 command = ''
176 175 for line in lines:
177 176 # skip blank lines so we don't mess up the prompt counter, but do
178 177 # NOT skip even a blank line if we are in a code block (more is
179 178 # true)
180 179 # if command is not empty trim the line
181 180 if command != '' :
182 181 line = line.strip()
183 182 # add the broken line to the command
184 183 if line and line[-1] == '\\' :
185 184 command += line[0:-1] + ' '
186 185 more = True
187 186 continue
188 187 else :
189 188 # add the last (current) line to the command
190 189 command += line
191 190 if command or more:
192 191 more = ip.IP.push(ip.IP.prefilter(command,more))
193 192 command = ''
194 193 # IPython's runsource returns None if there was an error
195 194 # compiling the code. This allows us to stop processing right
196 195 # away, so the user gets the error message at the right place.
197 196 if more is None:
198 197 break
199 198 # final newline in case the input didn't have it, so that the code
200 199 # actually does get executed
201 200 if more:
202 201 ip.IP.push('\n')
203 202
204 203 ip.IP.runlines = _runlines
205 204
206 205 main()
@@ -1,202 +1,200 b''
1 1 #!/usr/bin/env python
2 2
3 3 r""" mglob - enhanced file list expansion module
4 4
5 5 Use as stand-alone utility (for xargs, `backticks` etc.),
6 6 or a globbing library for own python programs. Globbing the sys.argv is something
7 7 that almost every Windows script has to perform manually, and this module is here
8 8 to help with that task. Also Unix users will benefit from enhanced modes
9 9 such as recursion, exclusion, directory omission...
10 10
11 11 Unlike glob.glob, directories are not included in the glob unless specified
12 12 with 'dir:'
13 13
14 14 'expand' is the function to use in python programs. Typical use
15 15 to expand argv (esp. in windows)::
16 16
17 17 try:
18 18 import mglob
19 19 files = mglob.expand(sys.argv[1:])
20 20 except ImportError:
21 21 print "mglob not found; try 'easy_install mglob' for extra features"
22 22 files = sys.argv[1:]
23 23
24 24 Note that for unix, shell expands *normal* wildcards (*.cpp, etc.) in argv.
25 25 Therefore, you might want to use quotes with normal wildcards to prevent this
26 26 expansion, in order for mglob to see the wildcards and get the wanted behaviour.
27 27 Not quoting the wildcards is harmless and typically has equivalent results, though.
28 28
29 29 Author: Ville Vainio <vivainio@gmail.com>
30 30 License: MIT Open Source license
31 31
32 32 """
33 33
34 34 #Assigned in variable for "usage" printing convenience"
35 35
36 36 globsyntax = """\
37 37 This program allows specifying filenames with "mglob" mechanism.
38 38 Supported syntax in globs (wilcard matching patterns)::
39 39
40 40 *.cpp ?ellowo*
41 41 - obvious. Differs from normal glob in that dirs are not included.
42 42 Unix users might want to write this as: "*.cpp" "?ellowo*"
43 43 rec:/usr/share=*.txt,*.doc
44 44 - get all *.txt and *.doc under /usr/share,
45 45 recursively
46 46 rec:/usr/share
47 47 - All files under /usr/share, recursively
48 48 rec:*.py
49 49 - All .py files under current working dir, recursively
50 50 foo
51 51 - File foo, or all files in dir foo
52 52 !*.bak readme*
53 53 - readme*, exclude files ending with .bak
54 54 !.svn/ !.hg/ !*_Data/ rec:.
55 55 - Skip .svn, .hg, foo_Data dirs (and their subdirs) in recurse.
56 56 Trailing / is the key, \ does not work!
57 57 dir:foo
58 58 - the directory foo (not files in foo)
59 59 dir:*
60 60 - all directories in current folder
61 61 foo.py bar.* !h* rec:*.py
62 62 - Obvious. !h* exclusion only applies for rec:*.py.
63 63 foo.py is *not* included twice.
64 64 @filelist.txt
65 65 - All files listed in 'filelist.txt' file, on separate lines.
66 66 """
67 67
68 68
69 69 __version__ = "0.2"
70 70
71 71
72 72 import os,glob,fnmatch,sys
73 73 from sets import Set as set
74 74
75 75
76 76 def expand(flist):
77 77 """ Expand the glob(s) in flist.
78 78
79 79 flist may be either a whitespace-separated list of globs/files
80 80 or an array of globs/files.
81 81
82 82 """
83 83 if isinstance(flist, basestring):
84 84 flist = flist.split()
85 85 done_set = set()
86 86 denied_set = set()
87 87
88 88 def recfind(p, pats = ["*"]):
89 89 denied_dirs = ["*" + d+"*" for d in denied_set if d.endswith("/")]
90 90 #print "de", denied_dirs
91 91 for (dp,dnames,fnames) in os.walk(p):
92 92 # see if we should ignore the whole directory
93 93 dp_norm = dp.replace("\\","/") + "/"
94 94 deny = False
95 95 #print "dp",dp
96 96 for deny_pat in denied_dirs:
97 97 if fnmatch.fnmatch( dp_norm, deny_pat):
98 98 deny = True
99 99 break
100 100 if deny:
101 101 continue
102 102
103 103
104 104 for f in fnames:
105 105 matched = False
106 106 for p in pats:
107 107 if fnmatch.fnmatch(f,p):
108 108 matched = True
109 109 break
110 110 if matched:
111 111 yield os.path.join(dp,f)
112 112
113 113 def once_filter(seq):
114 114 for it in seq:
115 115 p = os.path.abspath(it)
116 116 if p in done_set:
117 117 continue
118 118 done_set.add(p)
119 119 deny = False
120 120 for deny_pat in denied_set:
121 121 if fnmatch.fnmatch(os.path.basename(p), deny_pat):
122 122 deny = True
123 123 break
124 124 if not deny:
125 125 yield it
126 126 return
127 127
128 128 res = []
129 129
130 130 for ent in flist:
131 131 ent = os.path.expanduser(os.path.expandvars(ent))
132 132 if ent.lower().startswith('rec:'):
133 133 fields = ent[4:].split('=')
134 134 if len(fields) == 2:
135 135 pth, patlist = fields
136 136 elif len(fields) == 1:
137 137 if os.path.isdir(fields[0]):
138 138 # single arg is dir
139 139 pth, patlist = fields[0], '*'
140 140 else:
141 141 # single arg is pattern
142 142 pth, patlist = '.', fields[0]
143 143
144 144 elif len(fields) == 0:
145 145 pth, pathlist = '.','*'
146 146
147 147 pats = patlist.split(',')
148 148 res.extend(once_filter(recfind(pth, pats)))
149 149 # filelist
150 150 elif ent.startswith('@') and os.path.isfile(ent[1:]):
151 151 res.extend(once_filter(open(ent[1:]).read().splitlines()))
152 152 # exclusion
153 153 elif ent.startswith('!'):
154 154 denied_set.add(ent[1:])
155 155 # glob only dirs
156 156 elif ent.lower().startswith('dir:'):
157 157 res.extend(once_filter(filter(os.path.isdir,glob.glob(ent[4:]))))
158 158
159 159 # get all files in the specified dir
160 160 elif os.path.isdir(ent):
161 161 res.extend(once_filter(filter(os.path.isfile,glob.glob(ent + os.sep+"*"))))
162 162
163 163 # glob only files
164 164
165 165 elif '*' in ent or '?' in ent:
166 166 res.extend(once_filter(filter(os.path.isfile,glob.glob(ent))))
167 167
168 168 else:
169 169 res.extend(once_filter([ent]))
170 170 return res
171 171
172 172
173 173 def test():
174 174 assert (
175 175 expand("*.py ~/.ipython/*.py rec:/usr/share/doc-base") ==
176 176 expand( ['*.py', '~/.ipython/*.py', 'rec:/usr/share/doc-base'] )
177 177 )
178 178
179 179 def main():
180 180 if len(sys.argv) < 2:
181 181 print globsyntax
182 182 return
183 183
184 184 print "\n".join(expand(sys.argv[1:])),
185 185
186 186 def mglob_f(self, arg):
187 187 from IPython.genutils import SList
188 188 if arg.strip():
189 189 return SList(expand(arg))
190 190 print "Please specify pattern!"
191 191 print globsyntax
192 192
193 def ipython_install():
193 def init_ipython(ip):
194 194 """ register %mglob for IPython """
195 import IPython.ipapi
196 ip = IPython.ipapi.get()
197 195 mglob_f.__doc__ = globsyntax
198 196 ip.expose_magic("mglob",mglob_f)
199 197
200 198 # test()
201 199 if __name__ == "__main__":
202 200 main()
General Comments 0
You need to be logged in to leave comments. Login now