Python HOWTO

From Enso Wiki

Jump to: navigation, search

Contents

[edit] Warning

WARNING: This guide describes process for the official "Frozen" Enso with "Enso Developer prototype" installed. It is not guide for the "community" (open-source) Enso. If you want to participate in the Community Enso development, please follow the guide on Main Page



[edit] Setup

You'll need a computer running 32-bit Windows 2000, XP, or Vista. If you want to try other versions (like 2003 or XP64), then Enso might work, but it tends to break.

Beyond that, you'll need the Enso Developer Prototype installed, and you'll also need a recent version of Python installed. And that's pretty much it. (But the more extensions you have for Python, the more you'll be able to write cool commands).

[edit] Overview

You're going to write an XML-RPC server. When your server starts, it's going to contact Enso and say, "hey, I have commands A, B, and C." When the user issues command A, B, or C, Enso will contact your XML-RPC server: "you there, run the A command". At which point, you can do anything that is possible in Python.

For the sake of having an example, we're going to implement the "ooper case" command, which mimics Enso's own "upper case" command.

[edit] Your Enso Extension

Your XML-RPC server is called an "Enso Extension". It only needs to implement one method: the callCommand() method:

class MyEnsoExtension:
    def callCommand( self, commandName, postfix ):
        assert commandName == "ooper case"
        print "The oopercase command was executed, but it's not really implemented."
        return True

Note that there are two parameters that will be passed to this method: the name of the command, and the "postfix" or argument entered by the user (e.g., "open notepad", the postfix is notepad). There are different types of postfix, but for a simple command like "ooper case", you can safely ignore it, as it won't be used.

But in order for this extension to access the user's selection, you'll have to contact the Enso Developer Prototype's own XML-RPC endpoint. At the moment, this XML-RPC endpoint is available on port 11374 of your local host. The getUnicodeSelection() method will return the user's selected text. Then, when you've transformed it, you can replace the user's selection using the setUnicodeSelection() method:

import xmlrpclib
 
class MyEnsoExtension:
    def __init__( self ):
        self.enso = xmlrpclib.ServerProxy( "http://127.0.0.1:11374" )
 
    def callCommand( self, commandName, postfix ):
        assert commandName == "ooper case"
        selectedText = self.enso.getUnicodeSelection()
        returnText = selectedText.upper()
        self.enso.setUnicodeSelection( returnText, "ooper case" )
        return True

Note the second required parameter, which is the command name which is trying to set the user's selection. This is used if the user's selection can't be replaced -- for example, if they've selected text on a web site. In this case, the transformed text is displayed to the user in a transparent message, and is available for use with the "put" command.

And that's that; you've created your Enso Extension. You can extend it by making your callCommand() method support more command names.

[edit] Command Server

I as a developer found the above explanation of how to write a command overly complex when wanting to add multiple commands for what should be a simple process. So I decided to abstract the above code enough that you dont need to dead with the XMLRPC or create a new thread for each command (Threads are a limited resource so having too many can cause issues.)


I call my abstraction Command Server since it is taking care of the thread and XMLRPC interactions, leaving other command developers to just worry about actually writing their command. It would be nice if a version of this was integrated into Enso so people do not need to be running a second instance of python (Enso is the first instance) just to get custom commands written in python.