Skip to content

Commit 95f8d88

Browse files
authored
Merge pull request #862 from python-cmd2/docs_initialization
Improve the Sphinx docs for initialization
2 parents 3671619 + 9dcc207 commit 95f8d88

File tree

4 files changed

+207
-50
lines changed

4 files changed

+207
-50
lines changed

cmd2/cmd2.py

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,6 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
272272
# Otherwise it will be None. Its used to know when a pipe process can be killed and/or waited upon.
273273
self._cur_pipe_proc_reader = None
274274

275-
# Used by complete() for readline tab completion
276-
self.completion_matches = []
277-
278275
# Used to keep track of whether we are redirecting or piping output
279276
self._redirecting = False
280277

@@ -321,6 +318,38 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
321318
elif transcript_files:
322319
self._transcript_files = transcript_files
323320

321+
# Set the pager(s) for use with the ppaged() method for displaying output using a pager
322+
if sys.platform.startswith('win'):
323+
self.pager = self.pager_chop = 'more'
324+
else:
325+
# Here is the meaning of the various flags we are using with the less command:
326+
# -S causes lines longer than the screen width to be chopped (truncated) rather than wrapped
327+
# -R causes ANSI "style" escape sequences to be output in raw form (i.e. colors are displayed)
328+
# -X disables sending the termcap initialization and deinitialization strings to the terminal
329+
# -F causes less to automatically exit if the entire file can be displayed on the first screen
330+
self.pager = 'less -RXF'
331+
self.pager_chop = 'less -SRXF'
332+
333+
# This boolean flag determines whether or not the cmd2 application can interact with the clipboard
334+
self._can_clip = can_clip
335+
336+
# This determines the value returned by cmdloop() when exiting the application
337+
self.exit_code = 0
338+
339+
# This lock should be acquired before doing any asynchronous changes to the terminal to
340+
# ensure the updates to the terminal don't interfere with the input being typed or output
341+
# being printed by a command.
342+
self.terminal_lock = threading.RLock()
343+
344+
# Commands that have been disabled from use. This is to support commands that are only available
345+
# during specific states of the application. This dictionary's keys are the command names and its
346+
# values are DisabledCommand objects.
347+
self.disabled_commands = dict()
348+
349+
# If any command has been categorized, then all other commands that haven't been categorized
350+
# will display under this section in the help output.
351+
self.default_category = 'Uncategorized'
352+
324353
# The default key for sorting string results. Its default value performs a case-insensitive alphabetical sort.
325354
# If natural sorting is preferred, then set this to NATURAL_SORT_KEY.
326355
# cmd2 uses this key for sorting:
@@ -331,7 +360,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
331360

332361
############################################################################################################
333362
# The following variables are used by tab-completion functions. They are reset each time complete() is run
334-
# in reset_completion_defaults() and it is up to completer functions to set them before returning results.
363+
# in _reset_completion_defaults() and it is up to completer functions to set them before returning results.
335364
############################################################################################################
336365

337366
# If True and a single match is returned to complete(), then a space will be appended
@@ -345,6 +374,9 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
345374
# An optional header that prints above the tab-completion suggestions
346375
self.completion_header = ''
347376

377+
# Used by complete() for readline tab completion
378+
self.completion_matches = []
379+
348380
# Use this list if you are completing strings that contain a common delimiter and you only want to
349381
# display the final portion of the matches as the tab-completion suggestions. The full matches
350382
# still must be returned from your completer function. For an example, look at path_complete()
@@ -360,38 +392,6 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
360392
# If False, then complete() will sort the matches using self.default_sort_key before they are displayed.
361393
self.matches_sorted = False
362394

363-
# Set the pager(s) for use with the ppaged() method for displaying output using a pager
364-
if sys.platform.startswith('win'):
365-
self.pager = self.pager_chop = 'more'
366-
else:
367-
# Here is the meaning of the various flags we are using with the less command:
368-
# -S causes lines longer than the screen width to be chopped (truncated) rather than wrapped
369-
# -R causes ANSI "style" escape sequences to be output in raw form (i.e. colors are displayed)
370-
# -X disables sending the termcap initialization and deinitialization strings to the terminal
371-
# -F causes less to automatically exit if the entire file can be displayed on the first screen
372-
self.pager = 'less -RXF'
373-
self.pager_chop = 'less -SRXF'
374-
375-
# This boolean flag determines whether or not the cmd2 application can interact with the clipboard
376-
self._can_clip = can_clip
377-
378-
# This determines the value returned by cmdloop() when exiting the application
379-
self.exit_code = 0
380-
381-
# This lock should be acquired before doing any asynchronous changes to the terminal to
382-
# ensure the updates to the terminal don't interfere with the input being typed or output
383-
# being printed by a command.
384-
self.terminal_lock = threading.RLock()
385-
386-
# Commands that have been disabled from use. This is to support commands that are only available
387-
# during specific states of the application. This dictionary's keys are the command names and its
388-
# values are DisabledCommand objects.
389-
self.disabled_commands = dict()
390-
391-
# If any command has been categorized, then all other commands that haven't been categorized
392-
# will display under this section in the help output.
393-
self.default_category = 'Uncategorized'
394-
395395
# ----- Methods related to presenting output to the user -----
396396

397397
@property

docs/features/initialization.rst

Lines changed: 108 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ capabilities which you may wish to utilize while initializing the app::
66

77
#!/usr/bin/env python3
88
# coding=utf-8
9-
"""A simple example cmd2 appliction demonstrating the following:
10-
1) Colorizing/stylizing output
11-
2) Using multiline commands
12-
3) Persistent history
13-
4) How to run an initialization script at startup
14-
5) How to group and categorize commands when displaying them in help
15-
6) Opting-in to using the ipy command to run an IPython shell
16-
7) Allowing access to your application in py and ipy
17-
8) Displaying an intro banner upon starting your application
18-
9) Using a custom prompt
9+
"""A simple example cmd2 application demonstrating the following:
10+
1) Colorizing/stylizing output
11+
2) Using multiline commands
12+
3) Persistent history
13+
4) How to run an initialization script at startup
14+
5) How to group and categorize commands when displaying them in help
15+
6) Opting-in to using the ipy command to run an IPython shell
16+
7) Allowing access to your application in py and ipy
17+
8) Displaying an intro banner upon starting your application
18+
9) Using a custom prompt
19+
10) How to make custom attributes settable at runtime
1920
"""
2021
import cmd2
2122
from cmd2 import style
@@ -28,15 +29,27 @@ capabilities which you may wish to utilize while initializing the app::
2829
super().__init__(multiline_commands=['echo'], persistent_history_file='cmd2_history.dat',
2930
startup_script='scripts/startup.txt', use_ipython=True)
3031

32+
# Prints an intro banner once upon application startup
3133
self.intro = style('Welcome to cmd2!', fg='red', bg='white', bold=True)
34+
35+
# Show this as the prompt when asking for input
3236
self.prompt = 'myapp> '
3337

38+
# Used as prompt for multiline commands after the first line
39+
self.continuation_prompt = '... '
40+
3441
# Allow access to your application in py and ipy via self
3542
self.locals_in_py = True
3643

3744
# Set the default category name
3845
self.default_category = 'cmd2 Built-in Commands'
3946

47+
# Color to output text in with echo command
48+
self.foreground_color = 'cyan'
49+
50+
# Make echo_fg settable at runtime
51+
self.settable['foreground_color'] = 'Foreground color to use with echo command'
52+
4053
@cmd2.with_category(CUSTOM_CATEGORY)
4154
def do_intro(self, _):
4255
"""Display the intro banner"""
@@ -45,9 +58,93 @@ capabilities which you may wish to utilize while initializing the app::
4558
@cmd2.with_category(CUSTOM_CATEGORY)
4659
def do_echo(self, arg):
4760
"""Example of a multiline command"""
48-
self.poutput(arg)
61+
self.poutput(style(arg, fg=self.foreground_color))
4962

5063

5164
if __name__ == '__main__':
5265
app = BasicApp()
5366
app.cmdloop()
67+
68+
69+
Cmd class initializer
70+
---------------------
71+
72+
A ``cmd2.Cmd`` instance or subclass instance is an interactive CLI application
73+
framework. There is no good reason to instantiate ``Cmd`` itself; rather, it’s
74+
useful as a superclass of a class you define yourself in order to inherit
75+
``Cmd``’s methods and encapsulate action methods.
76+
77+
Certain things must be initialized within the ``__init__()`` method of your
78+
class derived from ``cmd2.Cmd``(all arguments to ``__init__()`` are optional):
79+
80+
.. automethod:: cmd2.cmd2.Cmd.__init__
81+
:noindex:
82+
83+
Cmd instance attributes
84+
-----------------------
85+
86+
The ``cmd2.Cmd`` class provides a large number of public instance attributes
87+
which allow developers to customize a ``cmd2`` application further beyond the
88+
options provided by the ``__init__()`` method.
89+
90+
Public instance attributes
91+
~~~~~~~~~~~~~~~~~~~~~~~~~~
92+
Here are instance attributes of ``cmd2.Cmd`` which developers might wish
93+
override:
94+
95+
- **broken_pipe_warning**: if non-empty, this string will be displayed if a
96+
broken pipe error occurs
97+
- **continuation_prompt**: used for multiline commands on 2nd+ line of input
98+
- **debug**: if ``True`` show full stack trace on error (Default: ``False``)
99+
- **default_category**: if any command has been categorized, then all other
100+
commands that haven't been categorized will display under this section in the
101+
help output.
102+
- **default_error**: the error that prints when a non-existent command is run
103+
- **default_sort_key**: the default key for sorting string results. Its default
104+
value performs a case-insensitive alphabetical sort.
105+
- **default_to_shell**: if ``True`` attempt to run unrecognized commands as
106+
shell commands (Default: ``False``)
107+
- **disabled_commands**: commands that have been disabled from use. This is to
108+
support commands that are only available during specific states of the
109+
application. This dictionary's keys are the command names and its values are
110+
DisabledCommand objects.
111+
- **echo**: if ``True``, each command the user issues will be repeated to the
112+
screen before it is executed. This is particularly useful when running
113+
scripts. This behavior does not occur when a running command at the prompt.
114+
(Default: ``False``)
115+
- **editor**: text editor program to use with *edit* command (e.g. ``vim``)
116+
- **exclude_from_history**: commands to exclude from the *history* command
117+
- **exit_code**: this determines the value returned by ``cmdloop()`` when
118+
exiting the application
119+
- **feedback_to_output**: if ``True`` send nonessential output to stdout, if
120+
``False`` send them to stderr (Default: ``False``)
121+
- **help_error**: the error that prints when no help information can be found
122+
- **hidden_commands**: commands to exclude from the help menu and tab
123+
completion
124+
- **last_result**: stores results from the last command run to enable usage
125+
of results in a Python script or interactive console. Built-in commands don't
126+
make use of this. It is purely there for user-defined commands and
127+
convenience.
128+
- **locals_in_py**: if ``True`` allow access to your application in *py*
129+
command via ``self`` (Default: ``False``)
130+
- **macros**: dictionary of macro names and their values
131+
- **max_completion_items**: max number of CompletionItems to display during
132+
tab-completion (Default: 50)
133+
- **pager**: sets the pager command used by the ``Cmd.ppaged()`` method for
134+
displaying wrapped output using a pager
135+
- **pager_chop**: sets the pager command used by the ``Cmd.ppaged()`` method
136+
for displaying chopped/truncated output using a pager
137+
- **py_bridge_name**: name by which embedded Python environments and scripts
138+
refer to the ``cmd2`` application by in order to call commands (Default:
139+
``app``)
140+
- **py_locals**: dictionary that defines specific variables/functions available
141+
in Python shells and scripts (provides more fine-grained control than making
142+
everything available with **locals_in_py**)
143+
- **quiet**: if ``True`` then completely suppress nonessential output (Default:
144+
``False``)
145+
- **quit_on_sigint**: if ``True`` quit the main loop on interrupt instead of
146+
just resetting prompt
147+
- **settable**: dictionary that controls which of these instance attributes
148+
are settable at runtime using the *set* command
149+
- **timing**: if ``True`` display execution time for each command (Default:
150+
``False``)

docs/features/settings.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ trace will be printed.
6969
echo
7070
~~~~
7171

72-
If ``True``, each command the user issues will be repeated to the screen before
73-
it is executed. This is particularly useful when running scripts. This
74-
behavior does not occur when a running command at the prompt.
72+
If ``True``, each command the user issues will be repeated to the screen
73+
before it is executed. This is particularly useful when running scripts.
74+
This behavior does not occur when a running command at the prompt.
7575

7676

7777
editor

examples/initialization.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
# coding=utf-8
3+
"""A simple example cmd2 application demonstrating the following:
4+
1) Colorizing/stylizing output
5+
2) Using multiline commands
6+
3) Persistent history
7+
4) How to run an initialization script at startup
8+
5) How to group and categorize commands when displaying them in help
9+
6) Opting-in to using the ipy command to run an IPython shell
10+
7) Allowing access to your application in py and ipy
11+
8) Displaying an intro banner upon starting your application
12+
9) Using a custom prompt
13+
10) How to make custom attributes settable at runtime
14+
"""
15+
import cmd2
16+
from cmd2 import style
17+
18+
19+
class BasicApp(cmd2.Cmd):
20+
CUSTOM_CATEGORY = 'My Custom Commands'
21+
22+
def __init__(self):
23+
super().__init__(multiline_commands=['echo'], persistent_history_file='cmd2_history.dat',
24+
startup_script='scripts/startup.txt', use_ipython=True)
25+
26+
# Prints an intro banner once upon application startup
27+
self.intro = style('Welcome to cmd2!', fg='red', bg='white', bold=True)
28+
29+
# Show this as the prompt when asking for input
30+
self.prompt = 'myapp> '
31+
32+
# Used as prompt for multiline commands after the first line
33+
self.continuation_prompt = '... '
34+
35+
# Allow access to your application in py and ipy via self
36+
self.locals_in_py = True
37+
38+
# Set the default category name
39+
self.default_category = 'cmd2 Built-in Commands'
40+
41+
# Color to output text in with echo command
42+
self.foreground_color = 'cyan'
43+
44+
# Make echo_fg settable at runtime
45+
self.settable['foreground_color'] = 'Foreground color to use with echo command'
46+
47+
@cmd2.with_category(CUSTOM_CATEGORY)
48+
def do_intro(self, _):
49+
"""Display the intro banner"""
50+
self.poutput(self.intro)
51+
52+
@cmd2.with_category(CUSTOM_CATEGORY)
53+
def do_echo(self, arg):
54+
"""Example of a multiline command"""
55+
self.poutput(style(arg, fg=self.foreground_color))
56+
57+
58+
if __name__ == '__main__':
59+
app = BasicApp()
60+
app.cmdloop()

0 commit comments

Comments
 (0)