##// END OF EJS Templates
Applied Joergen's patch for %run completer quote mismatch exception, closing #127.
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,230 +1,248 b''
1 1 """ Tab completion support for a couple of linux package managers
2 2
3 3 This is also an example of how to write custom completer plugins
4 4 or hooks.
5 5
6 6 Practical use:
7 7
8 8 [ipython]|1> import ipy_linux_package_managers
9 9 [ipython]|2> apt-get u<<< press tab here >>>
10 10 update upgrade
11 11 [ipython]|2> apt-get up
12 12
13 13 """
14 14 import IPython.ipapi
15 15 import glob,os,shlex,sys
16 16
17 17 ip = IPython.ipapi.get()
18 18
19 19 def vcs_completer(commands, event):
20 20 """ utility to make writing typical version control app completers easier
21 21
22 22 VCS command line apps typically have the format:
23 23
24 24 [sudo ]PROGNAME [help] [command] file file...
25 25
26 26 """
27 27
28 28
29 29 cmd_param = event.line.split()
30 30 if event.line.endswith(' '):
31 31 cmd_param.append('')
32 32
33 33 if cmd_param[0] == 'sudo':
34 34 cmd_param = cmd_param[1:]
35 35
36 36 if len(cmd_param) == 2 or 'help' in cmd_param:
37 37 return commands.split()
38 38
39 39 return ip.IP.Completer.file_matches(event.symbol)
40 40
41 41
42 42
43 43 def apt_completers(self, event):
44 44 """ This should return a list of strings with possible completions.
45 45
46 46 Note that all the included strings that don't start with event.symbol
47 47 are removed, in order to not confuse readline.
48 48
49 49 """
50 50 # print event # dbg
51 51
52 52 # commands are only suggested for the 'command' part of package manager
53 53 # invocation
54 54
55 55 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
56 56 # print cmd
57 57 if cmd.endswith('apt-get') or cmd.endswith('yum'):
58 58 return ['update', 'upgrade', 'install', 'remove']
59 59
60 60 # later on, add dpkg -l / whatever to get list of possible
61 61 # packages, add switches etc. for the rest of command line
62 62 # filling
63 63
64 64 raise IPython.ipapi.TryNext
65 65
66 66
67 67 # re_key specifies the regexp that triggers the specified completer
68 68
69 69 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
70 70 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
71 71
72 72 pkg_cache = None
73 73
74 74 def module_completer(self,event):
75 75 """ Give completions after user has typed 'import' """
76 76
77 77 # only a local version for py 2.4, pkgutil has no walk_packages() there
78 78 if sys.version_info < (2,5):
79 79 for el in [f[:-3] for f in glob.glob("*.py")]:
80 80 yield el
81 81 return
82 82
83 83 global pkg_cache
84 84 import pkgutil,imp,time
85 85 #current =
86 86 if pkg_cache is None:
87 87 print "\n\n[Standby while scanning modules, this can take a while]\n\n"
88 88 pkg_cache = list(pkgutil.walk_packages())
89 89
90 90 already = set()
91 91 for ld, name, ispkg in pkg_cache:
92 92 if name.count('.') < event.symbol.count('.') + 1:
93 93 if name not in already:
94 94 already.add(name)
95 95 yield name + (ispkg and '.' or '')
96 96 return
97 97
98 98 ip.set_hook('complete_command', module_completer, str_key = 'import')
99 99 ip.set_hook('complete_command', module_completer, str_key = 'from')
100 100
101 101 svn_commands = """\
102 102 add blame praise annotate ann cat checkout co cleanup commit ci copy
103 103 cp delete del remove rm diff di export help ? h import info list ls
104 104 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
105 105 pe propget pget pg proplist plist pl propset pset ps resolved revert
106 106 status stat st switch sw unlock update
107 107 """
108 108
109 109 def svn_completer(self,event):
110 110 return vcs_completer(svn_commands, event)
111 111
112 112 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
113 113
114 114 hg_commands = """
115 115 add addremove annotate archive backout branch branches bundle cat
116 116 clone commit copy diff export grep heads help identify import incoming
117 117 init locate log manifest merge outgoing parents paths pull push
118 118 qapplied qclone qcommit qdelete qdiff qfold qguard qheader qimport
119 119 qinit qnew qnext qpop qprev qpush qrefresh qrename qrestore qsave
120 120 qselect qseries qtop qunapplied recover remove rename revert rollback
121 121 root serve showconfig status strip tag tags tip unbundle update verify
122 122 version
123 123 """
124 124
125 125 def hg_completer(self,event):
126 126 """ Completer for mercurial commands """
127 127
128 128 return vcs_completer(hg_commands, event)
129 129
130 130 ip.set_hook('complete_command', hg_completer, str_key = 'hg')
131 131
132 132
133 133 bzr_commands = """
134 134 add annotate bind branch break-lock bundle-revisions cat check
135 135 checkout commit conflicts deleted diff export gannotate gbranch
136 136 gcommit gdiff help ignore ignored info init init-repository inventory
137 137 log merge missing mkdir mv nick pull push reconcile register-branch
138 138 remerge remove renames resolve revert revno root serve sign-my-commits
139 139 status testament unbind uncommit unknowns update upgrade version
140 140 version-info visualise whoami
141 141 """
142 142
143 143 def bzr_completer(self,event):
144 144 """ Completer for bazaar commands """
145 145 cmd_param = event.line.split()
146 146 if event.line.endswith(' '):
147 147 cmd_param.append('')
148 148
149 149 if len(cmd_param) > 2:
150 150 cmd = cmd_param[1]
151 151 param = cmd_param[-1]
152 152 output_file = (param == '--output=')
153 153 if cmd == 'help':
154 154 return bzr_commands.split()
155 155 elif cmd in ['bundle-revisions','conflicts',
156 156 'deleted','nick','register-branch',
157 157 'serve','unbind','upgrade','version',
158 158 'whoami'] and not output_file:
159 159 return []
160 160 else:
161 161 # the rest are probably file names
162 162 return ip.IP.Completer.file_matches(event.symbol)
163 163
164 164 return bzr_commands.split()
165 165
166 166 ip.set_hook('complete_command', bzr_completer, str_key = 'bzr')
167
167
168 def shlex_split(x):
169 """Helper function to split lines into segments."""
170 #shlex.split raise exception if syntax error in sh syntax
171 #for example if no closing " is found. This function keeps dropping
172 #the last character of the line until shlex.split does not raise
173 #exception. Adds end of the line to the result of shlex.split
174 #example: %run "c:/python -> ['%run','"c:/python']
175 endofline=[]
176 while x!="":
177 try:
178 comps=shlex.split(x)
179 if endofline>=1:
180 comps.append("".join(endofline))
181 return comps
182 except ValueError:
183 endofline=[x[-1:]]+endofline
184 x=x[:-1]
185 return ["".join(endofline)]
168 186
169 187 def runlistpy(self, event):
170 comps = shlex.split(event.line)
171 relpath = (len(comps) > 1 and comps[-1] or '')
172
188 comps = shlex_split(event.line)
189 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
190
173 191 #print "\nev=",event # dbg
174 192 #print "rp=",relpath # dbg
175 193 #print 'comps=',comps # dbg
176 194
177 195 lglob = glob.glob
178 196 isdir = os.path.isdir
179 197 if relpath.startswith('~'):
180 198 relpath = os.path.expanduser(relpath)
181 199 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
182 200 if isdir(f)]
183 201
184 202 # Find if the user has already typed the first filename, after which we
185 203 # should complete on all files, since after the first one other files may
186 204 # be arguments to the input script.
187 205 #filter(
188 206 if filter(lambda f: f.endswith('.py') or f.endswith('.ipy'),comps):
189 207 pys = [f.replace('\\','/') for f in lglob('*')]
190 208 else:
191 209 pys = [f.replace('\\','/')
192 210 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy')]
193 211 return dirs + pys
194 212
195 213 ip.set_hook('complete_command', runlistpy, str_key = '%run')
196 214
197 215 def cd_completer(self, event):
198 216 relpath = event.symbol
199 217 #print event # dbg
200 218 if '-b' in event.line:
201 219 # return only bookmark completions
202 220 bkms = self.db.get('bookmarks',{})
203 221 return bkms.keys()
204 222
205 223
206 224 if event.symbol == '-':
207 225 # jump in directory history by number
208 226 ents = ['-%d [%s]' % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
209 227 if len(ents) > 1:
210 228 return ents
211 229 return []
212 230
213 231 if relpath.startswith('~'):
214 232 relpath = os.path.expanduser(relpath).replace('\\','/')
215 233 found = []
216 234 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
217 235 if os.path.isdir(f)]:
218 236 if ' ' in d:
219 237 # we don't want to deal with any of that, complex code
220 238 # for this is elsewhere
221 239 raise IPython.ipapi.TryNext
222 240 found.append( d )
223 241
224 242 if not found:
225 243 if os.path.isdir(relpath):
226 244 return [relpath]
227 245 raise IPython.ipapi.TryNext
228 246 return found
229 247
230 248 ip.set_hook('complete_command', cd_completer, str_key = '%cd')
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now