summaryrefslogtreecommitdiff
path: root/docs/features/generating_output.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/features/generating_output.rst')
-rw-r--r--docs/features/generating_output.rst196
1 files changed, 147 insertions, 49 deletions
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.