Home Download Buy Blog Forum Support

Python help (simple)

Python help (simple)

Postby agibsonsw on Fri Mar 16, 2012 11:19 pm

Below is an alternative version of my PyHelp.py file. You might give it a key-binding such as:

Code: Select all
{ "keys": ["shift+f1"], "command": "py_help" }

Click into a (standard) Python function-name, method or attribute and press Shift+F1. An output panel will open with the help text extracted from the Python version you are using, or the status bar will advise that no help is available. (I was using the status-bar previously, but the output panel will show the full help text.)

There's a comment towards the bottom of the file which would hide the output panel after 5 seconds - uncomment this if you like.

I was examining the possibility of also extracting help text from any library that you may have imported. However, it doesn't seem that there is much help (via __doc__) in the standard (or sublime) libraries :?:

Code: Select all
import sublime, sublime_plugin

class PyHelpCommand(sublime_plugin.TextCommand):
   py_types = ('buffer', 'bytearray', 'complex', 'dict', 'file', 'float', 'frozenset', 'int',
      'list', 'long', 'memoryview', 'set', 'str', 'tuple', 'unicode', 'xrange')
   def run(self, edit):
      curr_view = self.view
      if not curr_view.match_selector(0, 'source.python'): return
      word = curr_view.substr(curr_view.word(curr_view.sel()[0].end())).lower()
      if word is None or len(word) <= 1:
         sublime.status_message('No word selected')
         return
      try:
         help_text = eval(word + '.__doc__')
         if help_text is not None:
            self.display_help(help_text)
            return
      except:
         pass
      for obj in PyHelpCommand.py_types:
         try:
            help_text = eval(obj + '.' + word + '.__doc__')
            if help_text is not None:
               self.display_help(help_text)
               return
         except:
            pass
      else:
         sublime.status_message('No help available')
      
   def display_help(self, help_text):
      win = sublime.active_window()
      the_output = win.get_output_panel('help_panel')
      win.run_command("show_panel", {"panel": "output." + "help_panel"})
      the_output.set_read_only(False)
      edit = the_output.begin_edit()
      the_output.insert(edit, the_output.size(), help_text)
      the_output.end_edit(edit)
      the_output.set_read_only(True)
      # sublime.set_timeout(self.hide_help, 5000)
   
   def hide_help(self):
      sublime.active_window().run_command("hide_panel", {"panel": "output." + "help_panel"})
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Python help (simple)

Postby riffito on Fri Mar 23, 2012 7:11 pm

Works nicely (when it does find something some __doc__ :D). Thanks!

It would be interesting mixing up this one with the Goto Documentation plugin.

Also, I should get off my laziness, and add in my "HelpMe" plugin (looks ups keywords in CHM files, based on code present on this thread).

Edit: Also try SublimeRope's "Show Documentation" command.
riffito
 
Posts: 17
Joined: Wed Dec 21, 2011 2:30 pm

Re: Python help (simple)

Postby agibsonsw on Fri Mar 23, 2012 8:27 pm

@riffito. Thank you :)

The version below looks for help() function text first, then __doc__ (help() is supposed to be more extensive). But if help text isn't found then there is a brief delay before it acknowledges that there is no help available. It could be extended in a number of ways - perhaps searching __class__.__doc__ or dir()?, or using the 'inspect' module - but I wanted it to be nice/simple/quick 8-)

How does Rope work: does it do an internet search - I assume not? If it finds help text (within project or library files) does it display in an output window?

I'll have a look at the information you've pointed me towards.. but I might also leave as is. Ta again, Andy.

Added: Actually, I've just noticed that the reason for the delay is that calling help() sends the whole of the help text to the console window, Doh!?! So it's probably best to stick with my previous code. [I'm not sure I can get around this behaviour?!]

Code: Select all
import sublime, sublime_plugin

class PyHelpCommand(sublime_plugin.TextCommand):
   py_types = (None, 'buffer', 'bytearray', 'complex', 'dict', 'file', 'float', 'frozenset',
      'int', 'list', 'long', 'memoryview', 'set', 'str', 'tuple', 'unicode', 'xrange')
   def run(self, edit):
      curr_view = self.view
      if not curr_view.match_selector(0, 'source.python'): return
      word = curr_view.substr(curr_view.word(curr_view.sel()[0].end())).lower()
      if word is None or len(word) <= 1:
         sublime.status_message('No word selected')
         return
      for obj in PyHelpCommand.py_types:
         try:
            if obj is None:
               help_text = help(word) or eval(word + '.__doc__')
            else:
               help_text = help(obj + '.' + word) or eval(obj + '.' + word + '.__doc__')
            if help_text is not None:
               self.display_help(help_text)
               return
         except:
            pass
      else:
         sublime.status_message('No help available')

   def display_help(self, help_text):
      win = sublime.active_window()
      the_output = win.get_output_panel('help_panel')
      the_output.set_read_only(False)
      edit = the_output.begin_edit()
      the_output.insert(edit, the_output.size(), help_text)
      the_output.end_edit(edit)
      the_output.set_read_only(True)
      win.run_command("show_panel", {"panel": "output." + "help_panel"})
      # sublime.set_timeout(self.hide_help, 5000)
   
   def hide_help(self):
      sublime.active_window().run_command("hide_panel", {"panel": "output." + "help_panel"})
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Python help (simple)

Postby riffito on Fri Mar 23, 2012 9:35 pm

agibsonsw wrote:@riffito. Thank you :)
How does Rope work: does it do an internet search - I assume not? If it finds help text (within project or library files) does it display in an output window?



It statically/dynamically analyzes the source code. No Internet search involved. Yes, it outputs to an "output_window".

I highly recommend you to give SublimeRope a try (IMO SublimeCodeIntel consumes too much disk space for what it does).

The rope library (bundled in SublimeRope) can be quite difficult to to grasp at first glance, but does wonders. For the specifics of how it extracts docs and calltips from source code (and how it does autocompletion) make sure to look at the "/rope/contrib/codeassist.py" file. Specially to the "PyDocExtractor" class.

I, for one, applaud your tinkering (how does one learns otherwise?), but in these specifics, I'd say:

* don't reinvent the wheel (if what you want is to get autocompletion/get_docs support)
* do reinvent the wheel (if what you want is to learn, possibly improve the existent wheel :D)
riffito
 
Posts: 17
Joined: Wed Dec 21, 2011 2:30 pm

Re: Python help (simple)

Postby riffito on Fri Mar 23, 2012 10:18 pm

agibsonsw wrote:Added: Actually, I've just noticed that the reason for the delay is that calling help() sends the whole of the help text to the console window, Doh!?! So it's probably best to stick with my previous code. [I'm not sure I can get around this behaviour?!]


The builtin "help()" is actually calling an instance of Helper class on the pydoc module. It does it like this:
Code: Select all
help = Helper(sys.stdin, sys.stdout)
.

I guess that you could simply create your own instance, using other 'file-like' objects so nothing gets written to stdout.
riffito
 
Posts: 17
Joined: Wed Dec 21, 2011 2:30 pm

Re: Python help (simple)

Postby agibsonsw on Fri Mar 23, 2012 10:46 pm

@riffito. Thank you, I shall have a look at this SublimeRope thing ;)

I'm studying/ tinkering with Python, ST (JSON, tmLanguage, etc. :D ). [This is why I resisted installing the Rope library in the first instance.] So I don't have a major project in mind; but if I create anything which I think might be helpful or interesting to others, I'm happy to post it.

Coincidently, I was reading something about 'stdout' very recently. I understand I can redirect it by creating a class with a 'write' method. But I don't think I will pursue this approach any further.

Regards, Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Python help (simple)

Postby agibsonsw on Fri Mar 23, 2012 10:52 pm

BTW At one stage I was considering the possibility of examining imported libraries, extracting its methods and attributes, dynamically creating completions from them (with named parameters as fields!) If there were help-text (somewhere..) for parameters it may even be possible to have this text appear in the status bar as the user completes the snippet fields. But my interest has waned on this subject :lol:
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Python help (simple)

Postby agibsonsw on Sat Mar 24, 2012 8:24 pm

Below is a slight revision/improvement to my 'PyHelp.py' file. By slightly re-ordering the list of types that it searches, and adding '__builtins__' and 'object' types, it is more likely to provide useful help (when using your assigned shortcut-combination). In particular, it will/should provide help on more of the built-in functions than it was previously.

Code: Select all
import sublime, sublime_plugin

class PyHelpCommand(sublime_plugin.TextCommand):
   py_types = (None, 'complex', 'dict', 'file', 'float', 'frozenset',
      'int', 'list', 'long', 'set', 'str', 'tuple', 'unicode', 'xrange',
      'bytearray', 'buffer', 'memoryview', '__builtins__', 'object')
   def run(self, edit):
      curr_view = self.view
      if not curr_view.match_selector(0, 'source.python'): return
      word = curr_view.substr(curr_view.word(curr_view.sel()[0].end())).lower()
      if word is None or len(word) <= 1:
         sublime.status_message('No word selected')
         return
      for obj in PyHelpCommand.py_types:
         try:
            if obj is None:
               help_text = eval(word + '.__doc__')
            else:
               help_text = eval(obj + '.' + word + '.__doc__')
            if help_text is not None:
               self.display_help(help_text)
               return
         except:
            pass
      else:
         sublime.status_message('No help available')

   def display_help(self, help_text):
      win = sublime.active_window()
      the_output = win.get_output_panel('help_panel')
      the_output.set_read_only(False)
      edit = the_output.begin_edit()
      the_output.insert(edit, the_output.size(), help_text)
      the_output.end_edit(edit)
      the_output.set_read_only(True)
      win.run_command("show_panel", {"panel": "output." + "help_panel"})
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm


Return to Plugin Announcements

Who is online

Users browsing this forum: No registered users and 5 guests