don't crash on files you can't read, el
[xo.git] / el
blobce25f3bd7db52802d1ad81c70b767e92972da8a8
1 #!/usr/bin/python
3 # a wrapper for $EDITOR
5 import os, re, readline, string, subprocess, sys
6 from optparse import OptionParser
8 _null_trans = string.maketrans("", "")
9 text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
11 editor = os.getenv('EDITOR')
13 def buildparser():
14 usage = "usage: %prog [-h] [-a] [regex1 regex2 ...]"
15 parser = OptionParser(usage=usage)
16 parser.add_option("-a", "--all",
17 action="store_true", dest="all", default=False,
18 help="show hidden files")
19 parser.add_option("-b", "--bin",
20 action="store_true", dest="bin", default=False,
21 help="show binary files")
22 return parser
24 def isbin(filename, blocksize=512):
25 f = open(filename).read(blocksize)
26 if f:
27 t = f.translate(_null_trans, text_characters)
28 if "\0" in f or len(t)/len(f) > 0.30:
29 return True
31 def getfiles(optall, optbin):
32 for fn in os.listdir('.'):
33 if (os.path.isfile(fn) and os.access(fn,os.R_OK) and
34 (optall or not fn.startswith('.')) and
35 (optbin or not isbin(fn))):
36 yield fn
38 def filterfiles(args, optall, optbin):
39 files = []
40 for fn in getfiles(optall,optbin):
41 if all(re.search(r,fn) for r in args):
42 files.append(fn)
43 return files
45 def choose(names):
46 if len(names) == 1:
47 name = names[0]
48 else:
49 for n, fn in enumerate(names):
50 print "%3d %-20s" % (n + 1, fn)
51 name = raw_input(" > ")
52 if name == "":
53 return
54 elif name.isdigit() and int(name) - 1 in range(len(names)):
55 return names[int(name) - 1]
56 else:
57 return name
59 def main():
60 if not editor:
61 print "$EDITOR not set"
62 return
63 parser = buildparser()
64 (opts, args) = parser.parse_args()
65 try:
66 name = choose(filterfiles(args, opts.all, opts.bin))
67 if name:
68 subprocess.Popen([editor, name]).wait()
69 except KeyboardInterrupt:
70 print
72 if __name__ == "__main__":
73 main()