Tuesday, November 11, 2008 8:27 PM
lynnGasch
Newbie experience writing a custom command
Since I am new to Ipad (like you!) and also new to Python, I thought I'd give you a little different take on the process of adding a custom command for ipad, along with the command itself. I apparently do things in a non-standard way, even when following instructions. The up-side is that I tend to uncover a lot of bugs that way. The down-side is that things don't always work first try. So, follow along with me to get a look at some troubleshooting and debugging as well.
I created a new python file and placed it in the Settings directory. I copied imports, initialization, and a command header from Commands.py. I renamed the command, gave it a new shortcut key, and defined it as just a simple writeline, using Core.Notify. I saved, reloaded settings (Ctrl+Alt+F5), and tried to execute it. I tried the shortcut key and executing by name, and I got no error but nothing seemed to happen either. Here are some steps I took to debug:
- Used the Help menu and chose Commands (or, Alt+F1). My command was showing up there but the shortcut key I assigned was not. It's possible that I duplicated a key combination that was already in use. If your command is not showing up in the list, make sure your file is in the Settings directory of the running ipad instance and has a python (.py) extension, and try reloading via Ctrl+Alt+F5. Refresh the Commands help to see it there. (I just changed my command keys to None -- that will be an issue to track down another day.)
- Tried executing the command by name. I learned that I needed to give the whole name, including the namespace that I had copy-pasted when I created the command:
- Used Visual Studio to attach to the Ipad process to debug the script. In VS, I opened the Commands.py file and my new file. I set a breakpoint in a Commands.py command, then called it in Ipad. I saw the breakpoint hit. Then I tried the same thing in my command. The breakpoint was not hit. What I discovered was that some text I had copy-pasted was indented too far, creating (I think) an essentially empty function definition (hey, I said I was new to Python too!). I unindented the line and voila, breakpoint hit.
Next, I swiped code from BuildProjectCommand to get the project items. I called Common.py OpenProjectItemHandler to actually open the items.
I discovered that for this to work, the .mproj had to be opened using 'Open Project' and not just 'Open'. This seemed to work ok with the Enumeration sample project. But, when I tried my command on the Relationships.mproj, which has 4 .m files, I got this error:

Intellipad nicely put the cursor on the error line in the file (I have highlighted it here). Ah, I see that this function wants a project context from the current view on each call, but our second call opened a .m file in the view that had contained our project buffer. Hmmm, maybe this is overkill and all I really need to do is call this:
Common.OpenUriInActiveView(uri, sender)
This does what I want. I thought my command had a side effect of opening a second buffer for the .mproj file itself, in MS Build Project mode rather than Project View mode. I added a line to skip any uris ending in ".mproj", but this didn't fix the problem. I found that issue elsewhere as well.
So, like I said, I tend to uncover a lot of bugs. I filed three as a result of this exercise:
- Opening the spurious project buffer
- Inability to toggle a project file between Project View and MS Build Modes
- Project context attributes not always tracked for buffers
The last 2 have to do with why you have to choose "Open Project" and can't just open a project file to get this to work. I did not institute any guards or error handling for these issues in my command -- I think moving on to actually fixing bugs is more important!