[cig-commits] r6121 - cs/pythia/trunk/pyre/applications
leif at geodynamics.org
leif at geodynamics.org
Mon Feb 26 20:48:24 PST 2007
Author: leif
Date: 2007-02-26 20:48:24 -0800 (Mon, 26 Feb 2007)
New Revision: 6121
Modified:
cs/pythia/trunk/pyre/applications/CommandlineParser.py
cs/pythia/trunk/pyre/applications/Executive.py
Log:
Issue5: Implemented simple Bash "programmable completion" for Pyre
apps. Add the following to your .bashrc to use:
complete -C "pyreapp -c" pyreapp
where 'pyreapp' is any Pyre application, e.g.,
complete -C "citcoms -c" citcoms
~~~ Benefits ~~~
Say you don't remember how to set the time limit for a job. Type
citcoms <TAB>
A list of all top-level properties and facilities is presented (plus
all .cfg and .pml files in the current working directory).
Hmmm. Perhaps it is under 'job'. So you continue typing:
citcoms --job.<TAB>
A list of the properties and facilities for 'job' appears. Ah, there
it is -- "job.walltime". But you are lazy, so you just type a 'w' and
hit <TAB> again:
citcoms --job.w<TAB>
And the shell completes "walltime" for you :-)
~~~ Limitations ~~~
Pyre will not help you with trait values:
myapp --foo=<TAB>
will do nothing. But in the future, it could print a list of valid
values for 'foo' in certain cases.
Currently, tab-completion does not work for apps which override the
default CommandlineParser. (There is exactly one such app: PyLith
v0.8.)
~~~ Bugs ~~~
If you override a facility setting on the command line, the
completions for traits of the corresponding component will be
wrong. E.g.,
myapp --solver=xyz --solver.<TAB>
will show you the traits for the solver set by default or in a
configuration file -- not necessarily those of the 'xyz' solver.
Modified: cs/pythia/trunk/pyre/applications/CommandlineParser.py
===================================================================
--- cs/pythia/trunk/pyre/applications/CommandlineParser.py 2007-02-27 00:57:27 UTC (rev 6120)
+++ cs/pythia/trunk/pyre/applications/CommandlineParser.py 2007-02-27 04:48:24 UTC (rev 6121)
@@ -25,6 +25,22 @@
return
+ def parseArgument(self, arg, prevArg):
+ if arg == "":
+ return self.prefixes[0], [], "", ""
+ candidate = self._filterNonOptionArgument(arg)
+ for p in self.prefixes:
+ if arg.startswith(p):
+ prefix = p
+ candidate = arg[len(p):]
+ break
+ else:
+ return None, None, None, arg
+ key, value = self._parseArgument(candidate)
+ fields = key.split(self.separator)
+ return prefix, fields, value, None
+
+
def __init__(self):
self.actions = {
'help': ['?', 'h'],
Modified: cs/pythia/trunk/pyre/applications/Executive.py
===================================================================
--- cs/pythia/trunk/pyre/applications/Executive.py 2007-02-27 00:57:27 UTC (rev 6120)
+++ cs/pythia/trunk/pyre/applications/Executive.py 2007-02-27 04:48:24 UTC (rev 6121)
@@ -93,7 +93,69 @@
def complete(self):
- # NYI: bash tab-completion
+ """perform shell command completion"""
+
+ from glob import glob
+ import os
+
+ arg, prevArg = self.unprocessedArguments[1:3]
+ if arg == "":
+ line = os.environ['COMP_LINE']
+ point = int(os.environ['COMP_POINT'])
+ if line[point - 1] == "=":
+ # NYI: value completion
+ return
+
+ parser = self.createCommandlineParser()
+ prefix, fields, value, filenameStem = parser.parseArgument(arg, prevArg)
+
+ # Match filenames.
+ if filenameStem is not None:
+ for codec in self.getCurator().codecs.itervalues():
+ extension = "." + codec.extension
+ if filenameStem:
+ pattern = "%s*" % filenameStem
+ for filename in glob(pattern):
+ if filename.endswith(extension):
+ print filename
+ else:
+ pattern = "%s*%s" % (filenameStem, extension)
+ for filename in glob(pattern):
+ print filename
+
+ # Match traits.
+ if fields is not None:
+ component = self
+ path = ""
+ for field in fields[:-1]:
+ facilityNames = component.inventory.facilityNames()
+ if not field in facilityNames:
+ return
+ path += field + "."
+ component = component.getTraitValue(field)
+ if fields:
+ field = fields[-1]
+ else:
+ field = ""
+ propertyNames = component.inventory.propertyNames()
+ candidates = []
+ for prop in propertyNames:
+ if prop.startswith(field):
+ candidates.append(prop)
+ if not candidates:
+ return
+ if len(candidates) == 1:
+ prop = candidates[0]
+ facilityNames = component.inventory.facilityNames()
+ if prop in facilityNames:
+ print "%s%s%s." % (prefix, path, prop)
+ print "%s%s%s=" % (prefix, path, prop)
+ else:
+ print "%s%s%s" % (prefix, path, prop)
+ else:
+ for prop in candidates:
+ print "%s%s%s" % (prefix, path, prop)
+
return
More information about the cig-commits
mailing list