Repository: python-cmd2/cmd2

Issue:
Strip escape codes when redirecting via ppaged()
Is there a reason ppaged doesn't strip escape codes when redirecting? Could look into creating a patch if it would be welcome.

Discussion:

Patch:
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 718f311f..6f9350c6 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -704,7 +704,7 @@ class Cmd(cmd.Cmd):
                             break
                     self.pipe_proc = None
                 else:
-                    self.stdout.write(msg_str)
+                    self.decolorized_write(self.stdout, msg_str)
             except BrokenPipeError:
                 # This occurs if a command's output is being piped to another process and that process closes before the
                 # command is finished. If you would like your application to print a warning message, then set the
diff --git a/docs/unfreefeatures.rst b/docs/unfreefeatures.rst
index 61c0601c..2cdc17ba 100644
--- a/docs/unfreefeatures.rst
+++ b/docs/unfreefeatures.rst
@@ -146,19 +146,20 @@ The output methods in the previous section all honor the ``colors`` setting,
 which has three possible values:
 
 Never
-    poutput() and pfeedback() strip all ANSI escape sequences
+    poutput(), pfeedback(), and ppaged() strip all ANSI escape sequences
     which instruct the terminal to colorize output
 
 Terminal
-    (the default value) poutput() and pfeedback() do not strip any ANSI escape
-    sequences when the output is a terminal, but if the output is a pipe or a
-    file the escape sequences are stripped. If you want colorized output you
-    must add ANSI escape sequences, preferably using some python color library
-    like `plumbum.colors`, `colorama`, `blessings`, or `termcolor`.
+    (the default value) poutput(), pfeedback(), and ppaged() do not strip any
+    ANSI escape sequences when the output is a terminal, but if the output is
+    a pipe or a file the escape sequences are stripped. If you want colorized
+    output you must add ANSI escape sequences, preferably using some python
+    color library like `plumbum.colors`, `colorama`, `blessings`, or
+    `termcolor`.
 
 Always
-    poutput() and pfeedback() never strip ANSI escape sequences, regardless of
-    the output destination
+    poutput(), pfeedback(), and ppaged() never strip ANSI escape sequences,
+    regardless of the output destination
 
 
 .. _quiet:
diff --git a/examples/colors.py b/examples/colors.py
index 8765aee0..2641ae44 100755
--- a/examples/colors.py
+++ b/examples/colors.py
@@ -9,19 +9,20 @@ different output colors ca
 The colors setting has three possible values:
 
 Never
-    poutput() and pfeedback() strip all ANSI escape sequences
+    poutput(), pfeedback(), and ppaged() strip all ANSI escape sequences
     which instruct the terminal to colorize output
 
 Terminal
-    (the default value) poutput() and pfeedback() do not strip any ANSI escape
-    sequences when the output is a terminal, but if the output is a pipe or a
-    file the escape sequences are stripped. If you want colorized output you
-    must add ANSI escape sequences, preferably using some python color library
-    like `plumbum.colors`, `colorama`, `blessings`, or `termcolor`.
+    (the default value) poutput(), pfeedback(), and ppaged() do not strip any
+    ANSI escape sequences when the output is a terminal, but if the output is
+    a pipe or a file the escape sequences are stripped. If you want colorized
+    output you must add ANSI escape sequences, preferably using some python
+    color library like `plumbum.colors`, `colorama`, `blessings`, or
+    `termcolor`.
 
 Always
-    poutput() and pfeedback() never strip ANSI escape sequences, regardless of
-    the output destination
+    poutput(), pfeedback(), and ppaged() never strip ANSI escape sequences,
+    regardless of the output destination
 """
 
 import random
diff --git a/examples/plumbum_colors.py b/examples/plumbum_colors.py
index 942eaf80..bfa07a74 100755
--- a/examples/plumbum_colors.py
+++ b/examples/plumbum_colors.py
@@ -9,19 +9,20 @@ different output colors ca
 The colors setting has three possible values:
 
 Never
-    poutput() and pfeedback() strip all ANSI escape sequences
+    poutput(), pfeedback(), and ppaged() strip all ANSI escape sequences
     which instruct the terminal to colorize output
 
 Terminal
-    (the default value) poutput() and pfeedback() do not strip any ANSI escape
-    sequences when the output is a terminal, but if the output is a pipe or a
-    file the escape sequences are stripped. If you want colorized output you
-    must add ANSI escape sequences, preferably using some python color library
-    like `plumbum.colors`, `colorama`, `blessings`, or `termcolor`.
+    (the default value) poutput(), pfeedback(), and ppaged() do not strip any
+    ANSI escape sequences when the output is a terminal, but if the output is
+    a pipe or a file the escape sequences are stripped. If you want colorized
+    output you must add ANSI escape sequences, preferably using some python
+    color library like `plumbum.colors`, `colorama`, `blessings`, or
+    `termcolor`.
 
 Always
-    poutput() and pfeedback() never strip ANSI escape sequences, regardless of
-    the output destination
+    poutput(), pfeedback(), and ppaged() never strip ANSI escape sequences,
+    regardless of the output destination
 
 WARNING: This example requires the plumbum package, which isn't normally required by cmd2.
 """


Test patch:
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 2dd08ff7..9bb85ffe 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -2109,6 +2109,24 @@ def test_ppaged(base_app):
     out = base_app.stdout.getvalue()
     assert out == msg + end
 
+def test_ppaged_strips_color_when_redirecting(base_app):
+    msg = 'testing...'
+    end = '\n'
+    base_app.colors = cmd2.constants.COLORS_TERMINAL
+    base_app.redirecting = True
+    base_app.ppaged(Fore.RED + msg)
+    out = base_app.stdout.getvalue()
+    assert out == msg + end
+
+def test_ppaged_strips_color_when_redirecting_if_always(base_app):
+    msg = 'testing...'
+    end = '\n'
+    base_app.colors = cmd2.constants.COLORS_ALWAYS
+    base_app.redirecting = True
+    base_app.ppaged(Fore.RED + msg)
+    out = base_app.stdout.getvalue()
+    assert out == Fore.RED + msg + end
+
 # we override cmd.parseline() so we always get consistent
 # command parsing by parent methods we don't override
 # don't need to test all the parsing logic here, because