summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2020-01-27 21:54:32 -0500
committerGitHub <noreply@github.com>2020-01-27 21:54:32 -0500
commit95f8d883496044bcb95ce803752a8851de6ad0e5 (patch)
tree1a2f2b11913c43cbd11a333411ff76ea34116529
parent3671619863dfc85f24d1ba9121ebd8bd3329b724 (diff)
parent9dcc2078d41ffeef1e1ac675d5809b535d76a81d (diff)
downloadcmd2-git-95f8d883496044bcb95ce803752a8851de6ad0e5.tar.gz
Merge pull request #862 from python-cmd2/docs_initialization
Improve the Sphinx docs for initialization
-rw-r--r--cmd2/cmd2.py72
-rw-r--r--docs/features/initialization.rst119
-rw-r--r--docs/features/settings.rst6
-rwxr-xr-xexamples/initialization.py60
4 files changed, 207 insertions, 50 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 900a2451..648aadb1 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -272,9 +272,6 @@ class Cmd(cmd.Cmd):
# Otherwise it will be None. Its used to know when a pipe process can be killed and/or waited upon.
self._cur_pipe_proc_reader = None
- # Used by complete() for readline tab completion
- self.completion_matches = []
-
# Used to keep track of whether we are redirecting or piping output
self._redirecting = False
@@ -321,6 +318,38 @@ class Cmd(cmd.Cmd):
elif transcript_files:
self._transcript_files = transcript_files
+ # Set the pager(s) for use with the ppaged() method for displaying output using a pager
+ if sys.platform.startswith('win'):
+ self.pager = self.pager_chop = 'more'
+ else:
+ # Here is the meaning of the various flags we are using with the less command:
+ # -S causes lines longer than the screen width to be chopped (truncated) rather than wrapped
+ # -R causes ANSI "style" escape sequences to be output in raw form (i.e. colors are displayed)
+ # -X disables sending the termcap initialization and deinitialization strings to the terminal
+ # -F causes less to automatically exit if the entire file can be displayed on the first screen
+ self.pager = 'less -RXF'
+ self.pager_chop = 'less -SRXF'
+
+ # This boolean flag determines whether or not the cmd2 application can interact with the clipboard
+ self._can_clip = can_clip
+
+ # This determines the value returned by cmdloop() when exiting the application
+ self.exit_code = 0
+
+ # This lock should be acquired before doing any asynchronous changes to the terminal to
+ # ensure the updates to the terminal don't interfere with the input being typed or output
+ # being printed by a command.
+ self.terminal_lock = threading.RLock()
+
+ # Commands that have been disabled from use. This is to support commands that are only available
+ # during specific states of the application. This dictionary's keys are the command names and its
+ # values are DisabledCommand objects.
+ self.disabled_commands = dict()
+
+ # If any command has been categorized, then all other commands that haven't been categorized
+ # will display under this section in the help output.
+ self.default_category = 'Uncategorized'
+
# The default key for sorting string results. Its default value performs a case-insensitive alphabetical sort.
# If natural sorting is preferred, then set this to NATURAL_SORT_KEY.
# cmd2 uses this key for sorting:
@@ -331,7 +360,7 @@ class Cmd(cmd.Cmd):
############################################################################################################
# The following variables are used by tab-completion functions. They are reset each time complete() is run
- # in reset_completion_defaults() and it is up to completer functions to set them before returning results.
+ # in _reset_completion_defaults() and it is up to completer functions to set them before returning results.
############################################################################################################
# If True and a single match is returned to complete(), then a space will be appended
@@ -345,6 +374,9 @@ class Cmd(cmd.Cmd):
# An optional header that prints above the tab-completion suggestions
self.completion_header = ''
+ # Used by complete() for readline tab completion
+ self.completion_matches = []
+
# Use this list if you are completing strings that contain a common delimiter and you only want to
# display the final portion of the matches as the tab-completion suggestions. The full matches
# still must be returned from your completer function. For an example, look at path_complete()
@@ -360,38 +392,6 @@ class Cmd(cmd.Cmd):
# If False, then complete() will sort the matches using self.default_sort_key before they are displayed.
self.matches_sorted = False
- # Set the pager(s) for use with the ppaged() method for displaying output using a pager
- if sys.platform.startswith('win'):
- self.pager = self.pager_chop = 'more'
- else:
- # Here is the meaning of the various flags we are using with the less command:
- # -S causes lines longer than the screen width to be chopped (truncated) rather than wrapped
- # -R causes ANSI "style" escape sequences to be output in raw form (i.e. colors are displayed)
- # -X disables sending the termcap initialization and deinitialization strings to the terminal
- # -F causes less to automatically exit if the entire file can be displayed on the first screen
- self.pager = 'less -RXF'
- self.pager_chop = 'less -SRXF'
-
- # This boolean flag determines whether or not the cmd2 application can interact with the clipboard
- self._can_clip = can_clip
-
- # This determines the value returned by cmdloop() when exiting the application
- self.exit_code = 0
-
- # This lock should be acquired before doing any asynchronous changes to the terminal to
- # ensure the updates to the terminal don't interfere with the input being typed or output
- # being printed by a command.
- self.terminal_lock = threading.RLock()
-
- # Commands that have been disabled from use. This is to support commands that are only available
- # during specific states of the application. This dictionary's keys are the command names and its
- # values are DisabledCommand objects.
- self.disabled_commands = dict()
-
- # If any command has been categorized, then all other commands that haven't been categorized
- # will display under this section in the help output.
- self.default_category = 'Uncategorized'
-
# ----- Methods related to presenting output to the user -----
@property
diff --git a/docs/features/initialization.rst b/docs/features/initialization.rst
index 936208f1..39e36428 100644
--- a/docs/features/initialization.rst
+++ b/docs/features/initialization.rst
@@ -6,16 +6,17 @@ capabilities which you may wish to utilize while initializing the app::
#!/usr/bin/env python3
# coding=utf-8
- """A simple example cmd2 appliction demonstrating the following:
- 1) Colorizing/stylizing output
- 2) Using multiline commands
- 3) Persistent history
- 4) How to run an initialization script at startup
- 5) How to group and categorize commands when displaying them in help
- 6) Opting-in to using the ipy command to run an IPython shell
- 7) Allowing access to your application in py and ipy
- 8) Displaying an intro banner upon starting your application
- 9) Using a custom prompt
+ """A simple example cmd2 application demonstrating the following:
+ 1) Colorizing/stylizing output
+ 2) Using multiline commands
+ 3) Persistent history
+ 4) How to run an initialization script at startup
+ 5) How to group and categorize commands when displaying them in help
+ 6) Opting-in to using the ipy command to run an IPython shell
+ 7) Allowing access to your application in py and ipy
+ 8) Displaying an intro banner upon starting your application
+ 9) Using a custom prompt
+ 10) How to make custom attributes settable at runtime
"""
import cmd2
from cmd2 import style
@@ -28,15 +29,27 @@ capabilities which you may wish to utilize while initializing the app::
super().__init__(multiline_commands=['echo'], persistent_history_file='cmd2_history.dat',
startup_script='scripts/startup.txt', use_ipython=True)
+ # Prints an intro banner once upon application startup
self.intro = style('Welcome to cmd2!', fg='red', bg='white', bold=True)
+
+ # Show this as the prompt when asking for input
self.prompt = 'myapp> '
+ # Used as prompt for multiline commands after the first line
+ self.continuation_prompt = '... '
+
# Allow access to your application in py and ipy via self
self.locals_in_py = True
# Set the default category name
self.default_category = 'cmd2 Built-in Commands'
+ # Color to output text in with echo command
+ self.foreground_color = 'cyan'
+
+ # Make echo_fg settable at runtime
+ self.settable['foreground_color'] = 'Foreground color to use with echo command'
+
@cmd2.with_category(CUSTOM_CATEGORY)
def do_intro(self, _):
"""Display the intro banner"""
@@ -45,9 +58,93 @@ capabilities which you may wish to utilize while initializing the app::
@cmd2.with_category(CUSTOM_CATEGORY)
def do_echo(self, arg):
"""Example of a multiline command"""
- self.poutput(arg)
+ self.poutput(style(arg, fg=self.foreground_color))
if __name__ == '__main__':
app = BasicApp()
app.cmdloop()
+
+
+Cmd class initializer
+---------------------
+
+A ``cmd2.Cmd`` instance or subclass instance is an interactive CLI application
+framework. There is no good reason to instantiate ``Cmd`` itself; rather, it’s
+useful as a superclass of a class you define yourself in order to inherit
+``Cmd``’s methods and encapsulate action methods.
+
+Certain things must be initialized within the ``__init__()`` method of your
+class derived from ``cmd2.Cmd``(all arguments to ``__init__()`` are optional):
+
+.. automethod:: cmd2.cmd2.Cmd.__init__
+ :noindex:
+
+Cmd instance attributes
+-----------------------
+
+The ``cmd2.Cmd`` class provides a large number of public instance attributes
+which allow developers to customize a ``cmd2`` application further beyond the
+options provided by the ``__init__()`` method.
+
+Public instance attributes
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Here are instance attributes of ``cmd2.Cmd`` which developers might wish
+override:
+
+- **broken_pipe_warning**: if non-empty, this string will be displayed if a
+ broken pipe error occurs
+- **continuation_prompt**: used for multiline commands on 2nd+ line of input
+- **debug**: if ``True`` show full stack trace on error (Default: ``False``)
+- **default_category**: if any command has been categorized, then all other
+ commands that haven't been categorized will display under this section in the
+ help output.
+- **default_error**: the error that prints when a non-existent command is run
+- **default_sort_key**: the default key for sorting string results. Its default
+ value performs a case-insensitive alphabetical sort.
+- **default_to_shell**: if ``True`` attempt to run unrecognized commands as
+ shell commands (Default: ``False``)
+- **disabled_commands**: commands that have been disabled from use. This is to
+ support commands that are only available during specific states of the
+ application. This dictionary's keys are the command names and its values are
+ DisabledCommand objects.
+- **echo**: if ``True``, each command the user issues will be repeated to the
+ screen before it is executed. This is particularly useful when running
+ scripts. This behavior does not occur when a running command at the prompt.
+ (Default: ``False``)
+- **editor**: text editor program to use with *edit* command (e.g. ``vim``)
+- **exclude_from_history**: commands to exclude from the *history* command
+- **exit_code**: this determines the value returned by ``cmdloop()`` when
+ exiting the application
+- **feedback_to_output**: if ``True`` send nonessential output to stdout, if
+ ``False`` send them to stderr (Default: ``False``)
+- **help_error**: the error that prints when no help information can be found
+- **hidden_commands**: commands to exclude from the help menu and tab
+ completion
+- **last_result**: stores results from the last command run to enable usage
+ of results in a Python script or interactive console. Built-in commands don't
+ make use of this. It is purely there for user-defined commands and
+ convenience.
+- **locals_in_py**: if ``True`` allow access to your application in *py*
+ command via ``self`` (Default: ``False``)
+- **macros**: dictionary of macro names and their values
+- **max_completion_items**: max number of CompletionItems to display during
+ tab-completion (Default: 50)
+- **pager**: sets the pager command used by the ``Cmd.ppaged()`` method for
+ displaying wrapped output using a pager
+- **pager_chop**: sets the pager command used by the ``Cmd.ppaged()`` method
+ for displaying chopped/truncated output using a pager
+- **py_bridge_name**: name by which embedded Python environments and scripts
+ refer to the ``cmd2`` application by in order to call commands (Default:
+ ``app``)
+- **py_locals**: dictionary that defines specific variables/functions available
+ in Python shells and scripts (provides more fine-grained control than making
+ everything available with **locals_in_py**)
+- **quiet**: if ``True`` then completely suppress nonessential output (Default:
+ ``False``)
+- **quit_on_sigint**: if ``True`` quit the main loop on interrupt instead of
+ just resetting prompt
+- **settable**: dictionary that controls which of these instance attributes
+ are settable at runtime using the *set* command
+- **timing**: if ``True`` display execution time for each command (Default:
+ ``False``)
diff --git a/docs/features/settings.rst b/docs/features/settings.rst
index 697c68a7..b8f75934 100644
--- a/docs/features/settings.rst
+++ b/docs/features/settings.rst
@@ -69,9 +69,9 @@ trace will be printed.
echo
~~~~
-If ``True``, each command the user issues will be repeated to the screen before
-it is executed. This is particularly useful when running scripts. This
-behavior does not occur when a running command at the prompt.
+If ``True``, each command the user issues will be repeated to the screen
+before it is executed. This is particularly useful when running scripts.
+This behavior does not occur when a running command at the prompt.
editor
diff --git a/examples/initialization.py b/examples/initialization.py
new file mode 100755
index 00000000..e26aac9f
--- /dev/null
+++ b/examples/initialization.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+# coding=utf-8
+"""A simple example cmd2 application demonstrating the following:
+ 1) Colorizing/stylizing output
+ 2) Using multiline commands
+ 3) Persistent history
+ 4) How to run an initialization script at startup
+ 5) How to group and categorize commands when displaying them in help
+ 6) Opting-in to using the ipy command to run an IPython shell
+ 7) Allowing access to your application in py and ipy
+ 8) Displaying an intro banner upon starting your application
+ 9) Using a custom prompt
+ 10) How to make custom attributes settable at runtime
+"""
+import cmd2
+from cmd2 import style
+
+
+class BasicApp(cmd2.Cmd):
+ CUSTOM_CATEGORY = 'My Custom Commands'
+
+ def __init__(self):
+ super().__init__(multiline_commands=['echo'], persistent_history_file='cmd2_history.dat',
+ startup_script='scripts/startup.txt', use_ipython=True)
+
+ # Prints an intro banner once upon application startup
+ self.intro = style('Welcome to cmd2!', fg='red', bg='white', bold=True)
+
+ # Show this as the prompt when asking for input
+ self.prompt = 'myapp> '
+
+ # Used as prompt for multiline commands after the first line
+ self.continuation_prompt = '... '
+
+ # Allow access to your application in py and ipy via self
+ self.locals_in_py = True
+
+ # Set the default category name
+ self.default_category = 'cmd2 Built-in Commands'
+
+ # Color to output text in with echo command
+ self.foreground_color = 'cyan'
+
+ # Make echo_fg settable at runtime
+ self.settable['foreground_color'] = 'Foreground color to use with echo command'
+
+ @cmd2.with_category(CUSTOM_CATEGORY)
+ def do_intro(self, _):
+ """Display the intro banner"""
+ self.poutput(self.intro)
+
+ @cmd2.with_category(CUSTOM_CATEGORY)
+ def do_echo(self, arg):
+ """Example of a multiline command"""
+ self.poutput(style(arg, fg=self.foreground_color))
+
+
+if __name__ == '__main__':
+ app = BasicApp()
+ app.cmdloop()