#@+leo-ver=4-thin
#@+node:ekr.20040919081244:@thin style_guide.py
"""
This is the plugin's docstring. Leo print's the __version__ variable (see
below) and this docstring when the user selects the plugin in the Plugins menu.
Therefore, this docstring should be a clear, concise description of what the
plugin does and how to use it.
"""

# This node and its decendents form a style guide for plugins.
# NOTE: Do NOT include either these initial comments or any of Python comments below.

#@@language python
#@@tabwidth -4

#@<< about this plugin >>
#@+node:ekr.20040919082800:<< about this plugin >>
#@+at
# 
# This node should contain a comment, starting with '@' as shown above.
# 
# Make sure you tell what your plugin does and how to use it. You may include 
# as
# much detail as you like, but please try to be as clear and concise as 
# possible.
# 
# This is not the place for ramblings, snippets of code that didn't work, 
# ideas
# for improvements etc.
#@-at
#@nonl
#@-node:ekr.20040919082800:<< about this plugin >>
#@nl
__version__ = "1.0"
#@<< version history >>
#@+node:ekr.20040919082800.1:<< version history >>
#@+at
# 
# This node should contain a comment, starting with '@' as shown above.
# 
# This comment should discuss what makes each version unique. Some people like 
# to
# include a date. You may do so if you like, but I have never found that
# useful...
# 
# 1.0 EKR:  The initial style guide.
#@-at
#@nonl
#@-node:ekr.20040919082800.1:<< version history >>
#@nl
#@<< imports >>
#@+node:ekr.20040919082800.2:<< imports >>
# The comments in this node would not be part of the actual plugin.
# Most plugins will include the following imports:
import leoGlobals as g
import leoPlugins

# Next would follow imports of Leo's modules.
# Note: it is almost never necessary to import leoNodes.

# Next would follow imports of any standard Python modules.
# Good Python style is to put each import on a separate line.
# Examples:
import os
import sys

# Please do _not_ assume that modules like Tkinter, Pmw, etc. are always available.
# A good way to test for the precence of such modules is as follows:
try:
    import Tkinter as Tk
except ImportError:
    Tk = g.cantImport("Tkinter")
    
try:
    import Pmw
except ImportError:
    Tk = g.cantImport("Pmw")
    
# As shown above, I prefer to abbreviate Tkinter as Tk
# Please do NOT abbreviate Pmw or leoPlugins.

# Please do NOT use either of the following kinds of imports.
# from m import *
# from m import x,y,z
#@nonl
#@-node:ekr.20040919082800.2:<< imports >>
#@nl
#@<< globals >>
#@+node:ekr.20040919082800.3:<< globals >>
#@+at
# 
# If your plugin uses lots of module-level globals, you may define them in 
# this
# section. You may also define a few globals in the root node.
# 
# However, having lots of globals is an indication that it might be best to
# recast your code using a class. The ivars of this class would replace the
# globals.
# 
# N.B. If your plugin uses data in an outline, it is almost always a bad idea 
# to
# access the data using g.top(). Instead, your plugin should define an 
# onCreate
# function as shown in nother nodes. onCreate will create a class instance in
# which self.c is bound to a single commander.
#@-at
#@nonl
#@-node:ekr.20040919082800.3:<< globals >>
#@nl

# PLEASE define each function or method in a separate node!
#@+others
#@+node:ekr.20040919084039:onCreate
#@+at
# 
# This is the recommended way of:
# - Avoiding global variables.  The ivars of myClass take the place of 
# globals.
# - Making sure that your plugin always acts on the proper commander.
#   All methods of myClass use self.c to get the command, NOT g.top().
# 
#@-at
#@@c

def onCreate(tag, keywords):
    
    """
    This function is called whenever a new Leo window gets created.
    
    It creates a class instance in which self.c is bound permanently to c.
    """

    c = keywords.get("c")
    
    # Creates a class instance in which self.c is bound permanently to c.
    myClassInstance = myClass(c)
    
    # Now you can reliably bind other events _for c_ to class methods.
    leoPlugins.registerHandler("a-hook-name",myClassInstance.doWhatever)
#@nonl
#@-node:ekr.20040919084039:onCreate
#@+node:ekr.20040919084723:class myClass
class myClass:
    
    """
    A class illustrating how to bind a class instance permanently to a _particular_ window.
    All methods of this class should use self.c rather than c = g.top().
    """
    
    # PLEASE define each method in a separate node!
    #@    @+others
    #@+node:ekr.20040919084723.1:myClass.__init__
    #@+at
    # 
    # Binding c to self.c as shown ensures that this class always acts on the 
    # same commander, regardless of what Leo window is presently on top.  This 
    # is crucial to having your plugin work properly when multiple Leo windows 
    # are open.
    # 
    #@-at
    #@@c
    
    def __init__ (self,c):
        
        self.c = c
    #@nonl
    #@-node:ekr.20040919084723.1:myClass.__init__
    #@+node:ekr.20040919085218:myClass.doWhatever
    def doWhatever (self):
        
        """
        A method showing how to get the proper commander.
        """
        
        # self.c is always the commander this method should use.
        c = self.c
        
        # Now do whatever you want with c.
    #@nonl
    #@-node:ekr.20040919085218:myClass.doWhatever
    #@-others
#@nonl
#@-node:ekr.20040919084723:class myClass
#@+node:ekr.20040919085752:onStart2
def onStart2 (tag, keywords):
    
    """
    Showing how to define a global hook that affects all commanders.
    """

    import leoTkinterFrame
    log = leoTkinterFrame.leoTkinterLog
    
    # Replace frame.put with newPut. (not shown).
    g.funcToMethod(newPut,log,"put")
#@nonl
#@-node:ekr.20040919085752:onStart2
#@-others

# You need this if statement ONLY if your plugin depends on modules that might not be available.
# See the imports section for more discussion.
if Tk and Pmw:
    # If your plugin needs to access data from a commander, it is almost always a bad
    # idea to use g.top() to get the commander of the presently selected frame.
    # Instead, use the onCreate function to create a class that binds self.c.
    leoPlugins.registerHandler("after-create-leo-frame", onCreate)
    
    # If your plugin acts globally (rather than on particular windows)
    # it is safe to define hook handlers here.  For example:
    leoPlugins.registerHandler("start2", onStart2)
    
    # Note: use g.plugin_signon, NOT leoPlugins.plugin_signon.
    # Please do not set __name__ explicitly.
    g.plugin_signon(__name__)
#@nonl
#@-node:ekr.20040919081244:@thin style_guide.py
#@-leo
