From 3ee91c36194c2f8cb41c9c81f9c034dca9c19daf 2012-06-13 20:26:16
From: Matthias BUSSONNIER <bussonniermatthias@gmail.com>
Date: 2012-06-13 20:26:16
Subject: [PATCH] take #!%...  prefix into account for completion

fixes #1767

---

diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py
index 1b3fa02..0cdae4b 100644
--- a/IPython/core/inputsplitter.py
+++ b/IPython/core/inputsplitter.py
@@ -96,6 +96,10 @@ ESC_QUOTE  = ','     # Split args on whitespace, quote each as string and call
 ESC_QUOTE2 = ';'     # Quote all args as a single string, call
 ESC_PAREN  = '/'     # Call first argument with rest of line as arguments
 
+ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
+                 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
+                 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
+
 #-----------------------------------------------------------------------------
 # Utilities
 #-----------------------------------------------------------------------------
diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py
index cd2a93c..9a08fde 100644
--- a/IPython/frontend/qt/console/console_widget.py
+++ b/IPython/frontend/qt/console/console_widget.py
@@ -5,7 +5,7 @@
 #-----------------------------------------------------------------------------
 
 # Standard library imports
-from os.path import commonprefix
+import os.path
 import re
 import sys
 from textwrap import dedent
@@ -16,6 +16,7 @@ from IPython.external.qt import QtCore, QtGui
 
 # Local imports
 from IPython.config.configurable import LoggingConfigurable
+from IPython.core.inputsplitter import ESC_SEQUENCES
 from IPython.frontend.qt.rich_text import HtmlExporter
 from IPython.frontend.qt.util import MetaQObjectHasTraits, get_font
 from IPython.utils.text import columnize
@@ -26,10 +27,32 @@ from completion_html import CompletionHtml
 from completion_plain import CompletionPlain
 from kill_ring import QtKillRing
 
+
 #-----------------------------------------------------------------------------
 # Functions
 #-----------------------------------------------------------------------------
 
+def commonprefix(items):
+    """Given a list of pathnames, returns the longest common leading component
+
+    Same function as os.path.commonprefix, but don't considere prefix made of
+    special caracters like #!$%... see
+
+    IPython.core.inputsplitter import ESC_SEQUENCES
+    """
+    # the last item will always have the least leading % symbol
+    prefixes = ''.join(ESC_SEQUENCES)
+    get_prefix = lambda x : x[0:-len(x.lstrip(prefixes))]
+    # min / max are first/last in alphabetical order
+    first_prefix = get_prefix(min(items))
+    last_prefix = get_prefix(max(items))
+
+    # common suffix is (common prefix of reversed items) reversed
+    prefix = os.path.commonprefix((first_prefix[::-1], last_prefix[::-1]))[::-1]
+
+    items = [ s.lstrip(prefixes) for s in items ]
+    return prefix+os.path.commonprefix(items)
+
 def is_letter_or_number(char):
     """ Returns whether the specified unicode character is a letter or a number.
     """