From 18358c8e0a0a8d262e79bf9457baea2d26fdac69 2010-09-12 22:58:47 From: Fernando Perez Date: 2010-09-12 22:58:47 Subject: [PATCH] Add %guiref to give a quick reference to the GUI console. --- diff --git a/IPython/core/usage.py b/IPython/core/usage.py index 78bdee6..5470f8f 100644 --- a/IPython/core/usage.py +++ b/IPython/core/usage.py @@ -281,17 +281,200 @@ The following magic functions are currently available: """ +gui_reference = """\ +=============================== + The IPython graphical console +=============================== + +This console is designed to emulate in many aspects the look, feel and workflow +typical of a terminal environment, but it adds support for a number of +enhancements that are simply not possible in a real terminal, such as inline +syntax highlighting, true multiline editing, inline graphics and much more. + +This quick reference document contains the basic information you'll need to +know to make the most efficient use of it. For the various command line +options available at startup, type ``--help`` at the command line. + + +Multiline editing +================= + +The graphical console is capable of true multiline editing, but it also tries +to behave intuitively like a terminal when possible. If you are used to +IPyhton's old terminal behavior, you should find the transition painless, and +once you learn a few basic keybindings it will be a much more efficient +environment. + +For single expressions or indented blocks, the console behaves almost like the +terminal IPython: single expressions are immediately evaluated *if the cursor +is at the end of the line*, and indented blocks are evaluated once a single +blank line is entered:: + + In [1]: print "Hello IPython!" # Enter was pressed at the end of the line + Hello IPython! + + In [2]: for i in range(10): + ...: print i, + ...: + 0 1 2 3 4 5 6 7 8 9 + +If you have a single expression and you go back to edit something in the +beginning, hitting ``Enter`` will split the line (like a text editor) instead +of executing it. To execute, you can either go to the end of the line to hit +``Enter``, or hit ``Shift-Enter`` anywhere, which is the 'force execution' +keybinding. + +If you want to enter more than one expression in a single input block +(something not possible in the terminal), you can use ``Control-Enter`` at the +end of your first line instead of ``Enter``. At that point the console goes +into 'cell mode' and even if your inputs are not indented, it will continue +accepting arbitrarily many lines until either you enter an extra blank line or +you hit ``Shift-Enter`` (the key binding that forces execution). When a +multiline cell is entered, IPython analyzes it and executes its code producing +an ``Out[n]`` prompt only for the last expression in it, while the rest of the +cell is executed as if it was a script. A few examples should clarify this:: + + + In [3]: x=1 # Hit C-Enter here + ...: y=2 # from now on, regular Enter is sufficient + ...: z=3 + ...: x**2 # This does *not* produce an Out[] value + ...: x+y+z # Only the last expression does + ...: + Out[3]: 6 + +The behavior where an extra blank line forces execution is only active if you +are actually typing at the keyboard each line, and is meant to make it mimic +the IPython terminal behavior. If you paste a long chunk of input (for example +a long script copied form an editor or web browser), it can contain arbitrarily +many intermediate blank lines and they won't cause any problems. You can then +make it execute by appending a blank line *at the end* or hitting +``Shift-Enter`` anywhere within the cell. + +With the up arrow key, you can retrieve previous blocks of input that contain +multiple lines. You can move inside of it like you would in any text editor. +When you want it executed, the simplest thing to do is to hit the force +execution key, ``Shift-Enter`` (though you can also navigate to the end and +append a blank line by using ``Enter`` twice). + +If you've edited a multiline cell and accidentally navigate out of it with the +up or down arrow keys, IPython will clear the cell and replace it with the +contents of the one above or below that you navigated to. If this was an +accident and you want to retrieve the cell you were editing, use the Undo +keybinding, ``Control-z``. + + +Key bindings +============ + +The IPython console supports most of the basic Emacs line-oriented +keybindings, in addition to some of its own. + +The keybinding prefixes mean: + +C : Control +S : Shift +M : Meta (typically the Alt key) + +The keybindings themselves are: + +Enter : insert new line (may cause execution, see above). +C-Enter : force new line, *never* causes execution. +S-Enter : *force* execution regardless of where cursor is, no newline added. +C-c : copy highlighted text to clipboard (prompts are automatically stripped). +C-v : paste text from clipboard. +C-z : undo (retrieves lost text if you move out of a cell with the arrows). +C-o : move to 'other' area, between pager and terminal. +C-l : clear terminal. +C-a : go to beginning of line. +C-e : go to end of line. +C-k : kill from cursor to the end of the line. +C-y : yank (paste) +C-p : previous line (like up arrow) +C-n : next line (like down arrow) +C-f : forward (like right arrow) +C-b : back (like left arrow) +C-d : delete next character. +M-d : delete next word. +M-Backspace : delete previous word. +C-. : forced restart of the kernel (a confirmation dialog appears). + + +The IPython pager +================= + +IPython will show long blocks of text from many sources using a builtin pager. +You can control where this pager appears with the ``--paging`` command-line +flag: + +- default: it is overlaid on top of the main terminal. You must quit the pager + to get back to the terminal (similar to how a kkk pager such as ``less`` + works). + +- vertical: the console is made double-tall, and the pager appears on the + bottom area when needed. You can view its contents while using the terminal. + +- horizontal: the console is made double-wide, and the pager appears on the + right area when needed. You can view its contents while using the terminal. + +If you use the vertical or horizontal paging modes, you can navigate between +terminal and pager as follows: + +- Tab key: goes from pager to terminal (but not the other way around). +- Control-o: goes from one to another always. +- Mouse: click on either. + +In all cases, the ``q`` or ``Escape`` keys quit the pager. + + +Running subprocesses +==================== + +The graphical IPython console uses the ``pexpect`` module to run subprocesses +when you type ``!command``. This has a number of advantages (true asynchronous +output from subprocesses as well as very robust termination of rogue +subprocesses with Control-C), as well as some limitations. The main limitation +is that you can *not* interact back with the subprocess, so anything that +invokes a pager or expects you to type input into it will block and hang (you +can kill it with Control-C). + +We have provided as magics ``%less`` (aliased to ``%more``), ``%clear`` to +clear the terminal, and ``%man`` on Linux/OSX to cover the most common commands +you'd want to call in your subshell, but you need to be aware of this +limitation. + + +Inline matplotlib graphics +========================== + +The IPython console is capable of displaying matplotlib figures inline, in SVG +format. If started with the ``--pylab inline`` flag, then all figures are +rendered inline automatically. If started with ``--pylab`` or ``--pylab +``, then a GUI backend will be used, but the ``paste()`` function +is added to the global and ``plt`` namespaces. You can paste any figure that +is currently open in a window with this function; type ``paste?`` for +additional details.""" + quick_guide = """\ ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. -object? -> Details about 'object'. ?object also works, ?? prints more.""" +object? -> Details about 'object', use 'object??' for extra details. +""" + +gui_note = """\ +%guiref -> A brief reference about the graphical user interface. +""" default_banner_parts = [ - 'Python %s' % (sys.version.split('\n')[0],), - 'Type "copyright", "credits" or "license" for more information.\n', - 'IPython %s -- An enhanced Interactive Python.' % (release.version,), + 'Python %s\n' % (sys.version.split('\n')[0],), + 'Type "copyright", "credits" or "license" for more information.\n\n', + 'IPython %s -- An enhanced Interactive Python.\n' % (release.version,), quick_guide ] -default_banner = '\n'.join(default_banner_parts) +default_gui_banner_parts = default_banner_parts + [gui_note] + +default_banner = ''.join(default_banner_parts) + +default_gui_banner = ''.join(default_gui_banner_parts) diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index 3d8c049..8ec67ee 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -21,7 +21,7 @@ from PyQt4 import QtCore, QtGui # Local imports from IPython.core.inputsplitter import IPythonInputSplitter, \ transform_ipy_prompt -from IPython.core.usage import default_banner +from IPython.core.usage import default_gui_banner from IPython.utils.traitlets import Bool, Str from frontend_widget import FrontendWidget @@ -248,7 +248,7 @@ class IPythonWidget(FrontendWidget): def _get_banner(self): """ Reimplemented to return IPython's default banner. """ - return default_banner + '\n' + return default_gui_banner def _process_execute_error(self, msg): """ Reimplemented for IPython-style traceback formatting. diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py index 35db62f..b0f8398 100644 --- a/IPython/frontend/terminal/interactiveshell.py +++ b/IPython/frontend/terminal/interactiveshell.py @@ -164,11 +164,11 @@ class TerminalInteractiveShell(InteractiveShell): self.write(banner) def compute_banner(self): - self.banner = self.banner1 + '\n' + self.banner = self.banner1 if self.profile: self.banner += '\nIPython profile: %s\n' % self.profile if self.banner2: - self.banner += '\n' + self.banner2 + '\n' + self.banner += '\n' + self.banner2 def init_usage(self, usage=None): if usage is None: diff --git a/IPython/zmq/zmqshell.py b/IPython/zmq/zmqshell.py index f3a7d00..d705e64 100644 --- a/IPython/zmq/zmqshell.py +++ b/IPython/zmq/zmqshell.py @@ -532,4 +532,14 @@ class ZMQInteractiveShell(InteractiveShell): """Find the man page for the given command and display in pager.""" page.page(self.shell.getoutput('man %s' % arg_s, split=False)) + # FIXME: this is specific to the GUI, so we should let the gui app load + # magics at startup that are only for the gui. Once the gui app has proper + # profile and configuration management, we can have it initialize a kernel + # with a special config file that provides these. + def magic_guiref(self, arg_s): + """Show a basic reference about the GUI console.""" + from IPython.core.usage import gui_reference + page.page(gui_reference) + + InteractiveShellABC.register(ZMQInteractiveShell)