diff options
Diffstat (limited to 'docs/features')
-rw-r--r-- | docs/features/builtin_commands.rst | 75 | ||||
-rw-r--r-- | docs/features/generating_output.rst | 196 | ||||
-rw-r--r-- | docs/features/index.rst | 1 | ||||
-rw-r--r-- | docs/features/settings.rst | 170 | ||||
-rw-r--r-- | docs/features/startup_commands.rst | 2 |
5 files changed, 354 insertions, 90 deletions
diff --git a/docs/features/builtin_commands.rst b/docs/features/builtin_commands.rst new file mode 100644 index 00000000..2a857339 --- /dev/null +++ b/docs/features/builtin_commands.rst @@ -0,0 +1,75 @@ +Builtin Commands +================ + +Applications which subclass :class:`cmd2.cmd2.Cmd` inherit a number of commands +which may be useful to your users. Developers can +:ref:`features/builtin_commands:Remove Builtin Commands` if they do not want +them to be part of the application. + +edit +---- + +This command launches an editor program and instructs it to open the given file +name. Here's an example: + +.. code-block:: text + + (Cmd) edit ~/.ssh/config + +The program to be launched is determined by the value of the +:ref:`features/settings:editor` setting. + + +set +--- + +A list of all user-settable parameters, with brief comments, is viewable from +within a running application: + +.. code-block:: text + + (Cmd) set --long + allow_style: Terminal # Allow ANSI text style sequences in output (valid values: Terminal, Always, Never) + continuation_prompt: > # On 2nd+ line of input + debug: False # Show full error stack on error + echo: False # Echo command issued into output + editor: vim # Program used by ``edit`` + feedback_to_output: False # include nonessentials in `|`, `>` results + locals_in_py: False # Allow access to your application in py via self + max_completion_items: 50 # Maximum number of CompletionItems to display during tab completion + prompt: (Cmd) # The prompt issued to solicit input + quiet: False # Don't print nonessential feedback + timing: False # Report execution times + +Any of these user-settable parameters can be set while running your app with +the ``set`` command like so: + +.. code-block:: text + + (Cmd) set allow_style Never + + +shell +----- + +Execute a command as if at the operating system shell prompt: + +.. code-block:: text + + (Cmd) shell pwd -P + /usr/local/bin + + +Remove Builtin Commands +----------------------- + +Developers may not want to offer the commands builtin to :class:`cmd2.cmd2.Cmd` +to users of their application. To remove a command you must delete the method +implementing that command from the :class:`cmd2.cmd2.Cmd` object at runtime. +For example, if you wanted to remove the :ref:`features/builtin_commands:shell` +command from your application:: + + class NoShellApp(cmd2.Cmd): + """A simple cmd2 application.""" + + delattr(cmd2.Cmd, 'do_shell') diff --git a/docs/features/generating_output.rst b/docs/features/generating_output.rst index e83b5fdf..f3d2a7f4 100644 --- a/docs/features/generating_output.rst +++ b/docs/features/generating_output.rst @@ -1,71 +1,169 @@ Generating Output ================= -how to generate output +A standard ``cmd`` application can produce output by using either of these +methods:: -- poutput -- perror -- paging -- exceptions -- color support + print("Greetings, Professor Falken.", file=self.stdout) + self.stdout.write("Shall we play a game?\n") -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: +While you could send output directly to ``sys.stdout``, :mod:`cmd2.cmd2.Cmd` +can be initialized with a ``stdin`` and ``stdout`` variables, which it stores +as ``self.stdin`` and ``self.stdout``. By using these variables every time you +produce output, you can trivially change where all the output goes by changing +how you initialize your class. -- 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()`` +:mod:`cmd2.cmd2.Cmd` extends this approach in a number of convenient ways. See +:ref:`features/redirection:Output Redirection And Pipes` for information on how +users can change where the output of a command is sent. In order for those +features to work, the output you generate must be sent to ``self.stdout``. You +can use the methods described above, and everything will work fine. +:mod:`cmd2.cmd2.Cmd` also includes a number of output related methods which you +may use to enhance the output your application produces. -.. automethod:: cmd2.cmd2.Cmd.poutput - :noindex: -.. automethod:: cmd2.cmd2.Cmd.perror - :noindex: -.. automethod:: cmd2.cmd2.Cmd.pfeedback - :noindex: -.. automethod:: cmd2.cmd2.Cmd.ppaged - :noindex: +Ordinary Output +--------------- -Suppressing non-essential output --------------------------------- +The :meth:`~.cmd2.Cmd.poutput` method is similar to the Python +`built-in print function <https://docs.python.org/3/library/functions.html#print>`_. :meth:`~.cmd2.Cmd.poutput` adds two +conveniences: -The ``quiet`` setting controls whether ``self.pfeedback()`` actually produces -any output. If ``quiet`` is ``False``, then the output will be produced. If -``quiet`` is ``True``, no output will be produced. + 1. Since users can pipe output to a shell command, it catches + ``BrokenPipeError`` and outputs the contents of + ``self.broken_pipe_warning`` to ``stderr``. ``self.broken_pipe_warning`` + defaults to an empty string so this method will just swallow the exception. + If you want to show an error message, put it in + ``self.broken_pipe_warning`` when you initialize :mod:`~cmd2.cmd2.Cmd`. -This makes ``self.pfeedback()`` useful for non-essential output like status -messages. Users can control whether they would like to see these messages by -changing the value of the ``quiet`` setting. + 2. It examines and honors the :ref:`features/settings:allow_style` setting. + See :ref:`features/generating_output:Colored Output` below for more details. + +Here's a simple command that shows this method in action:: + + def do_echo(self, args): + """A simple command showing how poutput() works""" + self.poutput(args) + + +Error Messages +-------------- + +When an error occurs in your program, you can display it on ``sys.stderr`` by +calling the :meth:`~.cmd2.Cmd.perror` method. By default this method applies +:meth:`cmd2.ansi.style_error` to the output. + + +Warning Messages +---------------- + +:meth:`~.cmd2.Cmd.pwarning` is just like :meth:`~.cmd2.Cmd.perror` but applies +:meth:`cmd2.ansi.style_warning` to the output. + + +Feedback +-------- + +You may have the need to display information to the user which is not intended +to be part of the generated output. This could be debugging information or +status information about the progress of long running commands. It's not +output, it's not error messages, it's feedback. If you use the +:ref:`features/settings:Timing` setting, the output of how long it took the +command to run will be output as feedback. You can use the +:meth:`~.cmd2.Cmd.pfeedback` method to produce this type of output, and +several :ref:`features/settings:Settings` control how it is handled. + +If the :ref:`features/settings:quiet` setting is ``True``, then calling +:meth:`~.cmd2.Cmd.pfeedback` produces no output. If +:ref:`features/settings:quiet` is ``False``, the +:ref:`features/settings:feedback_to_output` setting is consulted to determine +whether to send the output to ``stdout`` or ``stderr``. + + +Exceptions +---------- + +If your app catches an exception and you would like to display the exception to +the user, the :meth:`~.cmd2.Cmd.pexcept` method can help. The default behavior +is to just display the message contained within the exception. However, if the +:ref:`features/settings:debug` setting is ``True``, then the entire stack trace +will be displayed. + + +Paging Output +------------- + +If you know you are going to generate a lot of output, you may want to display +it in a way that the user can scroll forwards and backwards through it. If you +pass all of the output to be displayed in a single call to +:meth:`~.cmd2.Cmd.ppaged`, it will be piped to an operating system appropriate +shell command to page the output. On Windows, the output is piped to ``more``; +on Unix-like operating systems like MacOS and Linux, it is piped to ``less``. Colored Output -------------- -The output methods in the previous section all honor the ``allow_style`` -setting, which has three possible values: +You can add your own `ANSI escape sequences +<https://en.wikipedia.org/wiki/ANSI_escape_code#Colors>`_ to your output which +tell the terminal to change the foreground and background colors. If you want +to give yourself a headache, you can generate these by hand. You could also use +a Python color library like `plumbum.colors +<https://plumbum.readthedocs.io/en/latest/colors.html>`_, `colored +<https://gitlab.com/dslackw/colored>`_, or `colorama +<https://github.com/tartley/colorama>`_. Colorama is unique because when it's +running on Windows, it wraps ``stdout``, looks for ANSI escape sequences, and +converts them into the appropriate ``win32`` calls to modify the state of the +terminal. + +``cmd2`` imports and uses Colorama and provides a number of convenience methods +for generating colorized output, measuring the screen width of colorized +output, setting the window title in the terminal, and removing ANSI text style +escape codes from a string. These functions are all documentated in +:mod:`cmd2.ansi`. + +After adding the desired escape sequences to your output, you should use one of +these methods to present the output to the user: + +- :meth:`.cmd2.Cmd.poutput` +- :meth:`.cmd2.Cmd.perror` +- :meth:`.cmd2.Cmd.pwarning` +- :meth:`.cmd2.Cmd.pexcept` +- :meth:`.cmd2.Cmd.pfeedback` +- :meth:`.cmd2.Cmd.ppaged` + +These methods all honor the :ref:`features/settings:allow_style` setting, which +users can modify to control whether these escape codes are passed through to +the terminal or not. + + +Aligning Text +-------------- + +If you would like to generate output which is left, center, or right aligned within a +specified width or the terminal width, the following functions can help: + +- :meth:`cmd2.utils.align_left` +- :meth:`cmd2.utils.align_center` +- :meth:`cmd2.utils.align_right` -Never - poutput(), pfeedback(), and ppaged() strip all ANSI style sequences - which instruct the terminal to colorize output +These functions differ from Python's string justifying functions in that they support +characters with display widths greater than 1. Additionally, ANSI style sequences are safely +ignored and do not count toward the display width. This means colored text is supported. If +text has line breaks, then each line is aligned independently. -Terminal - (the default value) poutput(), pfeedback(), and ppaged() do not strip any - ANSI style sequences when the output is a terminal, but if the output is a - pipe or a file the style sequences are stripped. If you want colorized - output you must add ANSI style sequences using either cmd2's internal ansi - module or another color library such as `plumbum.colors`, `colorama`, or - `colored`. -Always - poutput(), pfeedback(), and ppaged() never strip ANSI style sequences, - regardless of the output destination -Colored and otherwise styled output can be generated using the `ansi.style()` -function: +Columnar Output +--------------- -.. automethod:: cmd2.ansi.style +When generating output in multiple columns, you often need to calculate the +width of each item so you can pad it appropriately with spaces. However, there +are categories of Unicode characters that occupy 2 cells, and other that occupy +0. To further complicate matters, you might have included ANSI escape sequences +in the output to generate colors on the terminal. +The :meth:`cmd2.ansi.style_aware_wcswidth` function solves both of these +problems. Pass it a string, and regardless of which Unicode characters and ANSI +text style escape sequences it contains, it will tell you how many characters on the +screen that string will consume when printed. diff --git a/docs/features/index.rst b/docs/features/index.rst index efeb9e6c..dc64badd 100644 --- a/docs/features/index.rst +++ b/docs/features/index.rst @@ -5,6 +5,7 @@ Features :maxdepth: 1 argument_processing + builtin_commands clipboard commands completion diff --git a/docs/features/settings.rst b/docs/features/settings.rst index f305a68c..627f61a9 100644 --- a/docs/features/settings.rst +++ b/docs/features/settings.rst @@ -1,68 +1,138 @@ Settings ======== -- current settings and what they do -- how a developer can add their own -- how to hide built in settings from a user +Settings provide a mechanism for a user to control the behavior of a ``cmd2`` +based application. A setting is stored in an instance attribute on your +subclass of :class:`cmd2.cmd2.Cmd` and must also appear in the +:attr:`cmd2.cmd2.Cmd.settable` dictionary. Developers may set default values +for these settings and users can modify them at runtime using the +:ref:`features/builtin_commands:set` command. Developers can +:ref:`features/settings:Create New Settings` and can also +:ref:`features/settings:Hide Builtin Settings` from the user. -Built In Settings + +Builtin Settings ----------------- -``cmd2`` has a number of built in settings, which a developer can set a default -value, and which users can modify to change the behavior of the application. +``cmd2`` has a number of builtin settings. These settings control the behavior +of certain application features and :ref:`features/builtin_commands:Builtin +Commands`. Users can use the :ref:`features/builtin_commands:set` command to +show all settings and to modify the value of any setting. -Timing -~~~~~~ +allow_style +~~~~~~~~~~~ + +Output generated by ``cmd2`` programs may contain ANSI escape seqences which +instruct the terminal to apply colors or text styling (i.e. bold) to the +output. The ``allow_style`` setting controls the behavior of these escape +sequences in output generated with any of the following methods: + +- :meth:`.cmd2.Cmd.poutput` +- :meth:`.cmd2.Cmd.perror` +- :meth:`.cmd2.Cmd.pwarning` +- :meth:`.cmd2.Cmd.pexcept` +- :meth:`.cmd2.Cmd.pfeedback` +- :meth:`.cmd2.Cmd.ppaged` + +This setting can be one of three values: + +- ``Never`` - all ANSI escape sequences which instruct the terminal to style + output are stripped from the output. + +- ``Terminal`` - (the default value) pass through ANSI escape sequences when + the output is being sent to the terminal, but if the output is redirected to + a pipe or a file the escape sequences are stripped. + +- ``Always`` - ANSI escape sequences are always passed through to the output + + +continuation_prompt +~~~~~~~~~~~~~~~~~~~ -Setting ``App.timing`` to ``True`` outputs timing data after every application -command is executed. |settable| +When a user types a :ref:`Multiline Command +<features/multiline_commands:Multiline Commands>` it may span more than one +line of input. The prompt for the first line of input is specified by the +:ref:`features/settings:prompt` setting. The prompt for subsequent lines of +input is defined by this setting. -Echo +debug +~~~~~ + +The default value of this setting is ``False``, which causes the +:meth:`~.cmd2.Cmd.pexcept` method to only display the message from an +exception. However, if the debug setting is ``True``, then the entire stack +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. +it is executed. This is particularly useful when running scripts. This behavior +does not occur when a running command at the prompt. -Debug -~~~~~ +editor +~~~~~~ + +Similar to the ``EDITOR`` shell variable, this setting contains the name of the +program which should be run by the :ref:`features/builtin_commands:edit` +command. + + +feedback_to_output +~~~~~~~~~~~~~~~~~~ -Setting ``App.debug`` to ``True`` will produce detailed error stacks whenever -the application generates an error. |settable| +Controls whether feedback generated with the :meth:`~cmd2.cmd2.Cmd.pfeedback` +method is sent to ``sys.stdout`` or ``sys.stderr``. If ``False`` the output +will be sent to ``sys.stderr`` -.. |settable| replace:: The user can ``set`` this parameter - during application execution. - (See :ref:`parameters`) +If ``True`` the output is sent to ``stdout`` (which is often the screen but may +be :ref:`redirected <features/redirection:Output Redirection and Pipes>`). The +feedback output will be mixed in with and indistinguishable from output +generated with :meth:`~cmd2.cmd2.Cmd.poutput`. -.. _parameters: -Other user-settable parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +locals_in_py +~~~~~~~~~~~~ -A list of all user-settable parameters, with brief -comments, is viewable from within a running application -with:: +Allow access to your application in one of the +:ref:`features/embedded_python_shells:Embedded Python Shells` via ``self``. - (Cmd) set --long - allow_style: Terminal # Allow ANSI text style sequences in output (valid values: Terminal, Always, Never) - continuation_prompt: > # On 2nd+ line of input - debug: False # Show full error stack on error - echo: False # Echo command issued into output - editor: vim # Program used by ``edit`` - feedback_to_output: False # include nonessentials in `|`, `>` results - locals_in_py: False # Allow access to your application in py via self - max_completion_items: 50 # Maximum number of CompletionItems to display during tab completion - prompt: (Cmd) # The prompt issued to solicit input - quiet: False # Don't print nonessential feedback - timing: False # Report execution times -Any of these user-settable parameters can be set while running your app with -the ``set`` command like so:: +max_completion_items +~~~~~~~~~~~~~~~~~~~~ - set allow_style Never +Maximum number of CompletionItems to display during tab completion. A CompletionItem +is a special kind of tab-completion hint which displays both a value and description +and uses one line for each hint. Tab complete the ``set`` command for an example. +If the number of tab-completion hints exceeds ``max_completion_items``, then they will +be displayed in the typical columnized format and will not include the description text +of the CompletionItem. + + +prompt +~~~~~~ + +This setting contains the string which should be printed as a prompt for user +input. + + +quiet +~~~~~ + +If ``True``, output generated by calling :meth:`~.cmd2.Cmd.pfeedback` is +suppressed. If ``False``, the :ref:`features/settings:feedback_to_output` +setting controls where the output is sent. + + +timing +~~~~~~ + +If ``True``, the elapsed time is reported for each command executed. Create New Settings @@ -100,3 +170,23 @@ changes a setting, and will receive both the old value and the new value. now: 13 (Cmd) sunbathe It's 13 C - are you a penguin? + + +Hide Builtin Settings +---------------------- + +You may want to prevent a user from modifying a builtin setting. A setting +must appear in the :attr:`cmd2.cmd2.Cmd.settable` dictionary in order for it +to be available to the :ref:`features/builtin_commands:set` command. + +Let's say your program does not have any +:ref:`features/multiline_commands:Multiline Commands`. You might want to hide +the :ref:`features/settings:continuation_prompt` setting from your users since +it is only applicable to multiline commands. To do so, remove it from the +:attr:`cmd2.cmd2.Cmd.settable` dictionary after you initialize your object:: + + class MyApp(cmd2.Cmd): + + def __init__(self): + super().__init__() + self.settable.pop('continuation_prompt') diff --git a/docs/features/startup_commands.rst b/docs/features/startup_commands.rst index 93984db6..aaaf7722 100644 --- a/docs/features/startup_commands.rst +++ b/docs/features/startup_commands.rst @@ -5,7 +5,7 @@ Startup Commands after your application starts up: 1. Commands at Invocation -1. Startup Script +2. Startup Script Commands run as part of a startup script are always run immediately after the application finishes initializing so they are guaranteed to run before any |