Mercurial > dotfiles
view unixSoft/bin/sednames.py @ 336:ea73ef5dc38c
emacs: avoid weird package.el breakage with newish packages
I've been toting around this package.el from 2009 or so, and something
in the package format seems to have changed that broke me. Thanks to
some related diagnostics by Lucas, I've grabbed the last package.el
that worked with emacs 23 and stashed it here. This seems to work,
modulo some things (notably js2-mode and smex) now seem to require
emacs 24 if you install them using package.el, so this will end up
being brittle on my last couple of emacs23 machines.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Thu, 29 May 2014 14:30:42 -0400 |
parents | 91dbdbea15e5 |
children |
line wrap: on
line source
#!/usr/bin/env python from itertools import imap as map from itertools import izip as zip import re whitespace_chars = { '\a': r'\a', '\b': r'\b', '\t': r'\t', '\n': r'\n', '\v': r'\v', '\f': r'\f', '\r': r'\r', } whitespace_chars_exp = re.compile('[' + ''.join(whitespace_chars) + ']') chars_to_escape = dict(zip(map(chr, xrange(0x00, 0x20)), ('\\' + ch for ch in map(chr, xrange(0x00, 0x20))))) for ch in '{}' "'" '"' '$*?': chars_to_escape[ch] = '\\' + ch for ch in whitespace_chars: del chars_to_escape[ch] # Let whitespace_chars handle these. chars_to_escape_exp = re.compile('[][\\' + ''.join(chars_to_escape) + ']') chars_to_escape['['] = '\[' chars_to_escape[']'] = '\]' chars_to_escape['\\'] = '\\\\' minimal_chars_to_escape_exp = re.compile("[\\']") def quote_argument(arg): count = 0 match = chars_to_escape_exp.search(arg) while match: count += 1 match = chars_to_escape_exp.search(arg, match.end()) else: del match if count > 2: arg = "'" + re.sub(minimal_chars_to_escape_exp, lambda match: '\\' + match.group(0), arg) + "'" else: arg = re.sub(chars_to_escape_exp, lambda match: chars_to_escape[match.group(0)], arg) arg = re.sub(whitespace_chars_exp, lambda match: whitespace_chars[match.group(0)], arg) return arg def custom_rename(option, opt_str, value, parser): for i, arg in enumerate(parser.rargs): if arg == ';': break parser.values.ensure_value('custom_rename', parser.rargs[:i]) del parser.rargs[:i + 1] import optparse parser = optparse.OptionParser(description="This program batch-renames files, optionally using a VCS (such as svn, hg, or bzr) or other external program to do the renaming. You specify the rename operations using sed commands, which you specify using the -e option.") parser.add_option('-e', '--program', action='append', default=['']) parser.add_option('--vcs', metavar='VCS', help='Version-control system with which to rename files, using <VCS> mv <SRC> <DST>; overridden by --custom-rename') parser.add_option('--custom-rename', help='Custom command to rename the file (e.g., hg mv); works like find(1) -exec (but with two {}, which are src and dst in that order), or you can use {SRC} and {DST}, or you can omit {...} entirely in which case src and dst will be appended in that order', action='callback', type=None, callback=custom_rename, default=None) parser.add_option('-q', '--quiet', action='store_true', default=False) opts, args = parser.parse_args() try: custom_rename = opts.custom_rename except AttributeError: try: custom_rename = [opts.vcs, 'mv'] except AttributeError: custom_rename = None def prefix_with_dash_e(seq): for arg in seq: yield '-e' yield arg import subprocess sed = subprocess.Popen(['sed', '-El'] + list(prefix_with_dash_e(opts.program)), stdin=subprocess.PIPE, stdout=subprocess.PIPE) import os, sys for src in args: sed.stdin.write(src + '\n') sed.stdin.flush() dst = sed.stdout.readline().rstrip('\n') if src == dst: if not opts.quiet: print >>sys.stderr, 'sed program did not transform %r - skipping' % (src,) else: if custom_rename: src_and_dst = [src, dst] rename_cmd = list(custom_rename) for i, arg in enumerate(rename_cmd): if arg == '{SRC}': rename_cmd[i] = src elif arg == '{DST}': rename_cmd[i] = dst elif arg == '{}': try: rename_cmd[i] = src_and_dst.pop(0) except IndexError: sys.exit('Too many {} arguments in custom rename command %r' % (custom_rename,)) else: rename_cmd += src_and_dst if not opts.quiet: print >>sys.stderr, ' '.join(map(quote_argument, rename_cmd)) subprocess.check_call(rename_cmd) else: if not opts.quiet: print >>sys.stderr, 'Renaming %r to %r' % (src, dst) os.rename(src, dst) sed.stdin.close() sys.exit(sed.wait())