Index: CallTips.py =================================================================== --- CallTips.py (revision 58672) +++ CallTips.py (working copy) @@ -8,6 +8,7 @@ import re import sys import types +import textwrap import CallTipWindow from HyperParser import HyperParser @@ -74,11 +75,12 @@ name = hp.get_expression() if not name or (not evalfuncs and name.find('(') != -1): return - arg_text = self.fetch_tip(name) - if not arg_text: + arg_text, doc = self.fetch_tip(name) + if not (arg_text or doc): return self.calltip = self._make_calltip_window() - self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1]) + self.calltip.showtip(name, arg_text, doc, + sur_paren[0], sur_paren[1]) def fetch_tip(self, name): """Return the argument list and docstring of a function or class @@ -129,6 +131,7 @@ def get_arg_text(ob): """Get a string describing the arguments for the given object""" arg_text = "" + doc = "" if ob is not None: arg_offset = 0 if type(ob) in (types.ClassType, types.TypeType): @@ -162,14 +165,8 @@ # See if we can use the docstring doc = getattr(ob, "__doc__", "") if doc: - doc = doc.lstrip() - pos = doc.find("\n") - if pos < 0 or pos> 70: - pos = 70 - if arg_text: - arg_text += "\n" - arg_text += doc[:pos] - return arg_text + doc = textwrap.dedent(doc).strip() + return arg_text, doc ################################################# # @@ -207,7 +204,7 @@ qualified_name = "%s.%s" % (t.im_class.__name__, name) except AttributeError: qualified_name = name - arg_text = ct.fetch_tip(qualified_name) + arg_text = ct.fetch_tip(qualified_name)[0] if arg_text != expected: failed.append(t) fmt = "%s - expected %s, but got %s" Index: CallTipWindow.py =================================================================== --- CallTipWindow.py (revision 58672) +++ CallTipWindow.py (working copy) @@ -6,11 +6,15 @@ """ from Tkinter import * +from configHandler import idleConf +import textView + HIDE_VIRTUAL_EVENT_NAME = "<>" HIDE_SEQUENCES = ("", "") CHECKHIDE_VIRTUAL_EVENT_NAME = "<>" CHECKHIDE_SEQUENCES = ("", "") CHECKHIDE_TIME = 100 # miliseconds +SHOW_FULL_DOC_EVENT_NAME = "<>" MARK_RIGHT = "calltipwindowregion_right" @@ -22,6 +26,7 @@ self.parenline = self.parencol = None self.lastline = None self.hideid = self.checkhideid = None + self.showfulldoc_seqs_and_id = None def position_window(self): """Check if needs to reposition the window, and if so - do it.""" @@ -44,10 +49,12 @@ y = box[1] + box[3] + self.widget.winfo_rooty() self.tipwindow.wm_geometry("+%d+%d" % (x, y)) - def showtip(self, text, parenleft, parenright): + def showtip(self, name, arg_text, doc, + parenleft, parenright): """Show the calltip, bind events which will close it and reposition it. """ # truncate overly long calltip + text = '\n'.join([x for x in [arg_text] + doc.splitlines()[:1] if x]) if len(text)>= 79: textlines = text.splitlines() for i, line in enumerate(textlines): @@ -89,6 +96,26 @@ for seq in HIDE_SEQUENCES: self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + if doc and (len(doc)>= 79 or '\n' in doc): + # bind the force-open-calltip sequence(s) to open the full + # doc-string in a new window + text = '' + if arg_text: text += name + arg_text + if text and doc: text += '\n\n' + text += doc + title = "In-code documentation for %s" % name + def show_full_doc_event(event): + textView.view_text(self.widget, title, text) + return "break" + seqs = idleConf.GetOption( + 'extensions', 'CallTips_cfgBindings', 'force-open-calltip', + type='str', default='') + seqs = seqs.split(' ') + for seq in seqs: + self.widget.event_add(SHOW_FULL_DOC_EVENT_NAME, seq) + id = self.widget.bind(SHOW_FULL_DOC_EVENT_NAME, show_full_doc_event) + self.showfulldoc_seqs_and_id = (seqs, id) + def checkhide_event(self, event=None): if not self.tipwindow: # If the event was triggered by the same event that unbinded @@ -122,6 +149,12 @@ self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) self.hideid = None + if self.showfulldoc_seqs_and_id is not None: + seqs, id = self.showfulldoc_seqs_and_id + for seq in seqs: + self.widget.event_delete(SHOW_FULL_DOC_EVENT_NAME, seq) + self.widget.unbind(SHOW_FULL_DOC_EVENT_NAME, id) + self.showfulldoc_seqs_and_id = None self.label.destroy() self.label = None @@ -158,7 +191,13 @@ root.mainloop() def calltip_show(self, event): - self.calltip.showtip("Hello world") + paren_left = self.text.index("insert") + paren_right = self.text.search(")", paren_left) + if not paren_right: + paren_right = "end" + self.calltip.showtip("God", "Hello world", + "Oh\nMy\nIt\nWorks!", + paren_left, paren_right) def calltip_hide(self, event): self.calltip.hidetip()

AltStyle によって変換されたページ (->オリジナル) /