Sublime Forum

Python help (simple)

#1

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

{ "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 :question:

[code]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"})[/code]
0 Likes

#2

Works nicely (when it does find something some doc :smiley:). 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.

0 Likes

#3

@riffito. Thank you :smile:

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 :sunglasses:

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. *

[code]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"})[/code]*
0 Likes

#4

[quote=“agibsonsw”]@riffito. Thank you :smile:
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?
[/quote]

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 :smiley:)*

0 Likes

#5

[quote=“agibsonsw”]
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. *
*

The builtin “help()” is actually calling an instance of Helper class on the pydoc module. It does it like this: 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.[/quote]

0 Likes

#6

@riffito. Thank you, I shall have a look at this SublimeRope thing :wink:

I’m studying/ tinkering with Python, ST (JSON, tmLanguage, etc. :smiley: ). [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.

0 Likes

#7

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 :laughing:

0 Likes

#8

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]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"})[/code]
0 Likes