Features requiring application changes¶
Multiline commands¶
Command input may span multiple lines for the
commands whose names are listed in the
parameter app.multilineCommands
. These
commands will be executed only
after the user has entered a terminator.
By default, the command terminators is
;
; replacing or appending to the list
app.terminators
allows different
terminators. A blank line
is always considered a command terminator
(cannot be overridden).
Parsed statements¶
cmd2
passes arg
to a do_
method (or
default
) as a ParsedString, a subclass of
string that includes an attribute parsed
.
parsed
is a pyparsing.ParseResults
object produced by applying a pyparsing
grammar applied to arg
. It may include:
- command
- Name of the command called
- raw
- Full input exactly as typed.
- terminator
- Character used to end a multiline command
- suffix
- Remnant of input after terminator
def do_parsereport(self, arg):
self.stdout.write(arg.parsed.dump() + '\n')
(Cmd) parsereport A B /* C */ D; E
['parsereport', 'A B D', ';', 'E']
- args: A B D
- command: parsereport
- raw: parsereport A B /* C */ D; E
- statement: ['parsereport', 'A B D', ';']
- args: A B D
- command: parsereport
- terminator: ;
- suffix: E
- terminator: ;
If parsed
does not contain an attribute,
querying for it will return None
. (This
is a characteristic of pyparsing.ParseResults
.)
The parsing grammar and process currently employed
by cmd2 is stable, but is likely significantly more
complex than it needs to be. Future cmd2
releases may
change it somewhat (hopefully reducing complexity).
(Getting arg
as a ParsedString
is
technically “free”, in that it requires no application
changes from the cmd standard, but there will
be no result unless you change your application
to use arg.parsed
.)
Environment parameters¶
Your application can define user-settable parameters which your code can
reference. First create a class attribute with the default value. Then
update the settable
dictionary with your setting name and a short
description before you initialize the superclass. Here’s an example, from
examples/environment.py
:
#!/usr/bin/env python
# coding=utf-8
"""
A sample application for cmd2 demonstrating customized environment parameters
"""
from cmd2 import Cmd
class EnvironmentApp(Cmd):
""" Example cmd2 application. """
degrees_c = 22
sunny = False
def __init__(self):
self.settable.update({'degrees_c': 'Temperature in Celsius'})
self.settable.update({'sunny': 'Is it sunny outside?'})
Cmd.__init__(self)
def do_sunbathe(self, arg):
if self.degrees_c < 20:
result = "It's {} C - are you a penguin?".format(self.degrees_c)
elif not self.sunny:
result = 'Too dim.'
else:
result = 'UV is bad for your skin.'
self.poutput(result)
def _onchange_degrees_c(self, old, new):
# if it's over 40C, it's gotta be sunny, right?
if new > 40:
self.sunny = True
if __name__ == '__main__':
c = EnvironmentApp()
c.cmdloop()
If you want to be notified when a setting changes (as we do above), then
define a method _onchange_{setting}()
. This method will be called after
the user changes a setting, and will receive both the old value and the new
value.
(Cmd) set --long | grep sunny
sunny: False # Is it sunny outside?
(Cmd) set --long | grep degrees
degrees_c: 22 # Temperature in Celsius
(Cmd) sunbathe
Too dim.
(Cmd) set degrees_c 41
degrees_c - was: 22
now: 41
(Cmd) set sunny
sunny: True
(Cmd) sunbathe
UV is bad for your skin.
(Cmd) set degrees_c 13
degrees_c - was: 41
now: 13
(Cmd) sunbathe
It's 13 C - are you a penguin?
Commands with flags¶
All do_
methods are responsible for interpreting
the arguments passed to them. However, cmd2
lets
a do_
methods accept Unix-style flags. It uses argparse
to parse the flags, and they work the same way as for
that module.
cmd2
defines a few decorators which change the behavior of
how arguments get parsed for and passed to a do_
method. See the section Argument Processing for more information.
Controlling how arguments are parsed for commands with flags¶
There are a couple functions which can globally effect how arguments are parsed for commands with flags:
-
cmd2.
set_posix_shlex
(val)¶ Allows user of cmd2 to choose between POSIX and non-POSIX splitting of args for decorated commands.
Parameters: val – bool - True => POSIX, False => Non-POSIX
-
cmd2.
set_strip_quotes
(val)¶ Allows user of cmd2 to choose whether to automatically strip outer-quotes when POSIX_SHLEX is False.
Parameters: val – bool - True => strip quotes on args for decorated commands if POSIX_SHLEX is False.
poutput, pfeedback, perror, ppaged¶
Standard cmd
applications produce their output with self.stdout.write('output')
(or with print
,
but print
decreases output flexibility). cmd2
applications can use
self.poutput('output')
, self.pfeedback('message')
, self.perror('errmsg')
, and self.ppaged('text')
instead. These methods have these advantages:
- Handle output redirection to file and/or pipe appropriately
- More concise
.pfeedback()
destination is controlled by quiet parameter.
- Option to display long output using a pager via
ppaged()
-
Cmd.
poutput
(msg, end='\n')¶ Convenient shortcut for self.stdout.write(); by default adds newline to end if not already present.
Also handles BrokenPipeError exceptions for when a commands’s output has been piped to another process and that process terminates before the cmd2 command is finished executing.
Parameters: - msg – str - message to print to current stdout - anything convertible to a str with ‘{}’.format() is OK
- end – str - string appended after the end of the message if not already present, default a newline
-
Cmd.
perror
(errmsg, exception_type=None, traceback_war=True)¶ Print error message to sys.stderr and if debug is true, print an exception Traceback if one exists.
Parameters: - errmsg – str - error message to print out
- exception_type – str - (optional) type of exception which precipitated this error message
- traceback_war – bool - (optional) if True, print a message to let user know they can enable debug
Returns:
-
Cmd.
pfeedback
(msg)¶ For printing nonessential feedback. Can be silenced with quiet. Inclusion in redirected output is controlled by feedback_to_output.
-
Cmd.
ppaged
(msg, end='\n')¶ Print output using a pager if it would go off screen and stdout isn’t currently being redirected.
Never uses a pager inside of a script (Python or text) or when output is being redirected or piped.
Parameters: - msg – str - message to print to current stdout - anything convertible to a str with ‘{}’.format() is OK
- end – str - string appended after the end of the message if not already present, default a newline
color¶
Text output can be colored by wrapping it in the colorize
method.
-
Cmd.
colorize
(val, color)¶ Given a string (
val
), returns that string wrapped in UNIX-style special characters that turn on (and then off) text color and style. If thecolors
environment parameter isFalse
, or the application is running on Windows, will returnval
unchanged.color
should be one of the supported strings (or styles): red/blue/green/cyan/magenta, bold, underline
quiet¶
Controls whether self.pfeedback('message')
output is suppressed;
useful for non-essential feedback that the user may not always want
to read. quiet
is only relevant if
app.pfeedback
is sometimes used.
select¶
Presents numbered options to user, as bash select
.
app.select
is called from within a method (not by the user directly; it is app.select
, not app.do_select
).
-
Cmd.
select
(opts, prompt='Your choice? ')¶ Presents a numbered menu to the user. Modelled after the bash shell’s SELECT. Returns the item chosen.
Argument
opts
can be:a single string -> will be split into one-word optionsa list of strings -> will be offered as optionsa list of tuples -> interpreted as (value, text), so that the return value can differ from the text advertised to the user
def do_eat(self, arg):
sauce = self.select('sweet salty', 'Sauce? ')
result = '{food} with {sauce} sauce, yum!'
result = result.format(food=arg, sauce=sauce)
self.stdout.write(result + '\n')
(Cmd) eat wheaties
1. sweet
2. salty
Sauce? 2
wheaties with salty sauce, yum!