[IPython-dev] [Pythonmac-SIG] readline support for OS X Leopard

Boyd Waters bwaters@nrao....
Wed Oct 31 12:43:03 CDT 2007


The segfault was in binding to the "complete" command; it does not  
segfault (and seems to work) if I bind to "rl_complete" instead.

*However*, I am not sure that this is what IPython wants.
I am going to assume that rl_complete is the correct thing (at the  
moment) and that IPython maps the appropriate completer via  
readline.set_completer().


We have a couple of problems, though.

A) The commands that are included in the default ipythonrc use  
readline syntax, and every one of them must be mapped to EditLine syntax

B) Passing plausible values into Leopard's readline.parse_and_bind  
causes a segmentation fault. Sometimes. When it's compiled Python.

Problem B is a bug report to Apple and I don't know for sure that I'll  
be able to fix.



Problem A - what to do about EditLine syntax in general - may best be  
left to the new user prefs stuff. I don't know.

What I am doing at the moment is hard-coding the mapping of the tab- 
completion as a special case in IPython's rilneimpl.py

I don't like that, but it works.

Also -- and a path to a Better World -- you can check IPython's  
rpimpl.py for a "uses_libedit" boolean value.   We could add some  
logic in iplib.py that checks this value and reads an alternate  
ipythonrc in case we're running on Leopard. I get nauseous thinking  
about it.

Anyway.


Here are a couple of kludges for the specific case of tab-completion  
on Leopard-python:



1) Explicitly check for libedit on Darwin and bind the tab to  
rl_complete if so:

--- IPython/rlineimpl.py	2007-10-30 17:34:13.000000000 -0600
+++ IPython/rlineimpl.py	2007-10-31 10:54:23.000000000 -0600
@@ -29,6 +29,16 @@
         print "Failed GetOutputFile"
         have_readline = False

+uses_libedit = False
+if sys.platform == 'darwin' and have_readline:
+    import commands
+    (status, result) = commands.getstatusoutput( "otool -L %s | grep  
libedit" % _rl.__file__ )
+    if status == 0 and len(result) > 0:
+        # we are bound to libedit - new in Leopard
+        _rl.parse_and_bind("bind ^I rl_complete")
+        print "Leopard libedit detected."
+        uses_libedit = True
+
# the clear_history() function was only introduced in Python 2.4 and is
# actually optional in the readline API, so we must explicitly check  
for its
# existence.  Some known platforms actually don't have it.  This thread:





2) Ignore any attempt to re-bind the tab key in the ipythonrc if we're  
using libedit:

--- IPython/iplib.py	2007-10-30 18:32:36.000000000 -0600
+++ IPython/iplib.py	2007-10-31 10:59:03.000000000 -0600
@@ -1325,7 +1325,10 @@
             if inputrc_name is None:
                 home_dir = get_home_dir()
                 if home_dir is not None:
-                    inputrc_name = os.path.join(home_dir,'.inputrc')
+                    inputrc_name = '.inputrc'
+                    if readline.uses_libedit:
+                        inputrc_name = '.editrc'
+                    inputrc_name = os.path.join(home_dir, inputrc_name)
             if os.path.isfile(inputrc_name):
                 try:
                     readline.read_init_file(inputrc_name)
@@ -1341,8 +1344,11 @@

             # Configure readline according to user's prefs
             for rlcommand in self.rc.readline_parse_and_bind:
-                print rlcommand
-                readline.parse_and_bind(rlcommand)
+                if rlcommand.startswith("tab"):
+                    pass
+                    if not readline.uses_libedit:
+                         print rlcommand
+                         readline.parse_and_bind(rlcommand)

             # remove some chars from the delimiters list
             delims = readline.get_completer_delims()




More information about the IPython-dev mailing list