comparison mercurial/dispatch.py @ 11989:f853873fc66d

aliases: provide more flexible ways to work with shell alias arguments This patch changes the functionality of shell aliases to add more powerful options for working with shell alias arguments. First: the alias name + arguments to a shell alias are set as an HG_ARGS environment variable, delimited by spaces. This matches the behavior of hooks. Second: any occurrences of "$@" (without quotes) are replaced with the arguments, separated by spaces. This happens *before* the alias gets to the shell. Third: any positive numeric variables ("$1", "$2", etc) are replaced with the appropriate argument, indexed from 1. "$0" is replaced with the name of the alias. Any "extra" numeric variables are replaced with an empty string. This happens *before* the alias gets to the shell. These changes allow for more flexible shell aliases: [alias] echo = !echo $@ count = !hg log -r "$@" --template='.' | wc -c | sed -e 's/ //g' qqueuemv = !mv "`hg root`/.hg/patches-$1" "`hg root`/.hg/patches-$2" In action: $ hg echo foo foo $ hg count 'branch(default)' 901 $ hg count 'branch(stable) and keyword(fixes)' 102 $ hg qqueuemv myfeature somefeature
author Steve Losh <steve@stevelosh.com>
date Wed, 18 Aug 2010 18:56:44 -0400
parents 81edef14922e
children 529e712cb1ba
comparison
equal deleted inserted replaced
11988:8380ed691df8 11989:f853873fc66d
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _ 8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback 9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
10 import util, commands, hg, fancyopts, extensions, hook, error 10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding 11 import cmdutil, encoding
12 import ui as uimod 12 import ui as uimod
13 13
14 def run(): 14 def run():
212 212
213 return 213 return
214 214
215 if self.definition.startswith('!'): 215 if self.definition.startswith('!'):
216 def fn(ui, *args): 216 def fn(ui, *args):
217 cmd = '%s %s' % (self.definition[1:], ' '.join(args)) 217 env = {'HG_ARGS': ' '.join((self.name,) + args)}
218 return util.system(cmd) 218 def _checkvar(m):
219 if int(m.groups()[0]) <= len(args):
220 return m.group()
221 else:
222 return ''
223 cmd = re.sub(r'\$(\d+)', _checkvar, self.definition[1:])
224 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
225 replace['0'] = self.name
226 replace['@'] = ' '.join(args)
227 cmd = util.interpolate(r'\$', replace, cmd)
228 return util.system(cmd, environ=env)
219 self.fn = fn 229 self.fn = fn
220 return 230 return
221 231
222 args = shlex.split(self.definition) 232 args = shlex.split(self.definition)
223 cmd = args.pop(0) 233 cmd = args.pop(0)
272 282
273 def __call__(self, ui, *args, **opts): 283 def __call__(self, ui, *args, **opts):
274 if self.shadows: 284 if self.shadows:
275 ui.debug("alias '%s' shadows command\n" % self.name) 285 ui.debug("alias '%s' shadows command\n" % self.name)
276 286
277 return util.checksignature(self.fn)(ui, *args, **opts) 287 if self.definition.startswith('!'):
288 return self.fn(ui, *args, **opts)
289 else:
290 return util.checksignature(self.fn)(ui, *args, **opts)
278 291
279 def addaliases(ui, cmdtable): 292 def addaliases(ui, cmdtable):
280 # aliases are processed after extensions have been loaded, so they 293 # aliases are processed after extensions have been loaded, so they
281 # may use extension commands. Aliases can also use other alias definitions, 294 # may use extension commands. Aliases can also use other alias definitions,
282 # but only if they have been defined prior to the current definition. 295 # but only if they have been defined prior to the current definition.