Repository: Qiskit/qiskit

Issue:
line_length in text drawer needs a default
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Informations

- **Qiskit Terra version**: master
- **Python version**:
- **Operating system**:

### What is the current behavior?
Large circuits are scrambled when using the text-based circuit drawer.

![image](https://user-images.githubusercontent.com/1249193/47883034-ed28ae80-de01-11e8-9aa9-7f51a9a5ec56.png)

vs

<img width="824" alt="screen shot 2018-11-01 at 6 16 35 pm" src="https://user-images.githubusercontent.com/1249193/47883114-48f33780-de02-11e8-9c5d-9448bf45364c.png">




### Steps to reproduce the problem
Make a large circuit and draw it.


### What is the expected behavior?



### Suggested solutions
Have the text-based circuit wrap according to the size of the terminal or Jupyter notebook cell width, and split like the Matplotlib version does.




Discussion:
Did you try setting line_length option up?
That works, but why is it not set to some default value, say 80, that works for any circuit?
I think there are ways to know the dimension of the console that the code is running. However, I don't know how portable they are.

I have the feeling that 80 is very short for most of the modern scenarios.

Please, rename the issue to reflect the new enhancement request. Something like "line_length in text drawer needs a default", or similar.
There is a stdlib call in the shutil module: https://docs.python.org/3/library/shutil.html#querying-the-size-of-the-output-terminal. If it can't figure it out it falls back to assuming an 80x24 terminal. This is what I used when adding a `__str__` method to the QuantumCircuit class in #911.
Let's use the tag `type:bug` for things that are broken. That is, they raise unexpected exceptions or/and the functionality that used to work now is not working. The `type:enhancement` tag is for things that work, but you prefer them to work differently. Or for additional funtionality that does not exists right now. 
@mtreinish it seems very stright forward. Let's go for it. If I implemented it in the visualizer, would you remove it from the `__str__`?
Yes, if the text drawer automatically sizes the output by default there would be no reason to specify that for `__str__` in #911 

Resolving patch:
diff --git a/qiskit/tools/visualization/_circuit_visualization.py b/qiskit/tools/visualization/_circuit_visualization.py
--- a/qiskit/tools/visualization/_circuit_visualization.py
+++ b/qiskit/tools/visualization/_circuit_visualization.py
@@ -86,8 +86,12 @@ def circuit_drawer(circuit,
             the default will change.
         interactive (bool): when set true show the circuit in a new window
             (cannot inline in Jupyter). Note when used with the latex_source
-            output type this has no effect
-        line_length (int): sets the length of the lines generated by `text`
+            output type this has no effect.
+        line_length (int): Sets the length of the lines generated by `text`
+            output type. This useful when the drawing does not fit in the
+            console. If None (default), it will try to guess the console width
+            using shutil.get_terminal_size(). If you don't want pagination at
+            all, set `line_length=-1`.
         reverse_bits (bool): When set to True reverse the bit order inside
             registers for the output visualization.
         plot_barriers (bool): Enable/disable drawing barriers in the output
@@ -330,8 +334,11 @@ def _text_circuit_drawer(circuit, filename=None,
         circuit (QuantumCircuit): Input circuit
         filename (str): optional filename to write the result
         basis (str): Optional. Comma-separated list of gate names
-        line_length (int): Optional. Sometimes, your console is too small of the drawing. Give me
-                           you maximum line length your console supports.
+        line_length (int): Optional. Breaks the circuit drawing to this length. This
+                   useful when the drawing does not fit in the console. If
+                   None (default), it will try to guess the console width using
+                   shutil.get_terminal_size(). If you don't want pagination
+                   at all, set line_length=-1.
         reversebits (bool): Rearrange the bits in reverse order.
         plotbarriers (bool): Draws the barriers when they are there.
     Returns:
diff --git a/qiskit/tools/visualization/_text.py b/qiskit/tools/visualization/_text.py
--- a/qiskit/tools/visualization/_text.py
+++ b/qiskit/tools/visualization/_text.py
@@ -10,6 +10,7 @@
 """
 
 from itertools import groupby
+from shutil import get_terminal_size
 
 from ._error import VisualizationError
 
@@ -452,12 +453,18 @@ def lines(self, line_length=None):
         """
         Generates a list with lines. These lines form the text drawing.
         Args:
-            line_length (int): Optional. When given, breaks the circuit drawing to this length. This
-                               useful when the drawing does not fit in the console.
+            line_length (int): Optional. Breaks the circuit drawing to this length. This
+                               useful when the drawing does not fit in the console. If
+                               None (default), it will try to guess the console width using
+                               shutil.get_terminal_size(). If you don't want pagination
+                               at all, set line_length=-1.
 
         Returns:
             list: A list of lines with the text drawing.
         """
+        if line_length is None:
+            line_length, _ = get_terminal_size()
+
         noqubits = self.json_circuit['header']['number_of_qubits']
         layers = self.build_layers()
 
@@ -476,8 +483,8 @@ def lines(self, line_length=None):
 
             TextDrawing.normalize_width(layer)
 
-            if line_length is None:
-                # does not page
+            if line_length == -1:
+                # Do not use pagination (aka line breaking. aka ignore line_length).
                 layer_groups[-1].append(layer)
                 continue
 


Test patch:
diff --git a/test/python/test_circuit_text_drawer.py b/test/python/test_circuit_text_drawer.py
--- a/test/python/test_circuit_text_drawer.py
+++ b/test/python/test_circuit_text_drawer.py
@@ -100,6 +100,15 @@ def test_text_pager(self):
         circuit.cx(qr[0], qr[1])
         self.assertEqual(_text_circuit_drawer(circuit, line_length=20), expected)
 
+    def test_text_no_pager(self):
+        """ The pager can be disable."""
+        qr = QuantumRegister(1, 'q')
+        circuit = QuantumCircuit(qr)
+        for _ in range(100):
+            circuit.h(qr[0])
+        amount_of_lines = _text_circuit_drawer(circuit, line_length=-1).count('\n')
+        self.assertEqual(amount_of_lines, 2)
+
 
 @unittest.skipUnless(VALID_MATPLOTLIB, 'osx matplotlib backend not available')
 class TestTextDrawerGatesInCircuit(QiskitTestCase):
diff --git a/test/python/test_visualization_output.py b/test/python/test_visualization_output.py
--- a/test/python/test_visualization_output.py
+++ b/test/python/test_visualization_output.py
@@ -111,7 +111,7 @@ def test_matplotlib_drawer(self):
     def test_text_drawer(self):
         filename = self._get_resource_path('current_textplot.txt')
         qc = self.sample_circuit()
-        output = circuit_drawer(qc, filename=filename, output="text")
+        output = circuit_drawer(qc, filename=filename, output="text", line_length=-1)
         self.assertFilesAreEqual(filename, self.text_reference)
         os.remove(filename)
         try: