More thoughts on Linglish

I still don’t have a decent name for “Linglish”, the toy scripting language for the Linux desktop that I was playing around with a couple of days ago. I’ve added a couple more features to satisfy my curiosity about how hard it would be to do, and I’ve read the comments on the previous post with a great deal of interest. Thanks to everyone who chimed in with thoughts.

First, what Linglish can now do:

tell screensaver to lock

A simple command: just tell one application to do one thing.

ask banshee‘s engine for uri

Request the value of something from an application. If you do this from the command-line, the value is printed out:

$ python linglish/runner.py -c "ask banshee's engine for uri"
file:///home/aquarius/Music/New%20Order%20-%20World%20in%20Motion).MP3

tell banshee‘s engine to pause

tell screensaver to lock

Run more than one command in a script

tell tomboy to FindStartHereNote

tell tomboy to displaynote with the result

Call a command which returns something and then do something based on that: Tomboy has no “show the Start Here note” function, but this does it fine by getting a reference to the Start Here note and then displaying it. The latter command could also have been written as tell tomboy to displaynote it or tell tomboy to displaynote FindStartHereNote

wait for banshee‘s eventchanged

ask banshee for currenturi

tell tomboy to createnote with it

Wait for an application (Banshee) to send a signal (a song has stopped playing or started), then when it happens ask for the value of a property (the path to the currently-playing song), and finally call a different app (Tomboy) to create a note with that path as its name. This example will then exit: if you want to create a new note every time the song changes, then wait repeatedly for the signal rather than just waiting for it.

Next, some musings:

One thing that this has revealed to me is that there are quite a few apps which I’d like to interact over D-Bus with which don’t provide an API to do so. The glaringly obvious example here is Nautilus (and indeed there is a bug requesting a D-Bus API), and a part (a small part) of why I’ve built this is that if there’s an easy way to encourage people to write little programs controlling their desktop then that will encourage application developers to build APIs to their apps. Zenity doesn’t have one either, which makes interaction from these little Linglish scripts a bit difficult; I suppose I could build “display dialog” commands into the language but that seems a bit off. On the other hand, one of the advantages here is that there’s nothing stopping someone building a thing which is just a D-Bus API and which then calls out to Zenity to do the work. A second is that our D-Bus APIs are not necessarily brilliant. Picking a silly example, if you want to find Tomboy’s version using Linglish you have to tell tomboy to version, which sounds rather stupid; it should be “ask tomboy for version”, but Version() is a method rather than a property in Tomboy’s D-Bus API. (I’m not picking on Tomboy here; they have a pretty comprehensive API, and I’ve been testing and developing Linglish using primarily Tomboy and Banshee.) Linglish is sort of designed with the conceit that methods are verbs, hence the “tell someapp to dosomething” syntax, which sounds deeply weird if your methods are not actually a verb. It’s also jolly hard to work out what D-Bus APIs are actually available. Well, that’s not true: if you’re me, or a hacker like me, then you can use J5’s fantastic D-Feet D-Bus browser. I think this problem is best solved with tools used to create the language rather than the language itself, although there’s more on this in the future-development section below. There were plenty of comments on the last post saying that this was a stupid idea and that it made much more sense to have a syntax like screensaver/lock or screensaver.lock() rather than tell screensaver to lock. I, personally, do not agree with that. I’m not necessarily suggesting that I’m right and they’re wrong, or that neophytes will indeed find my way easier: just that this is an alternative way. If you think that Python or Smalltalk or any one of a dozen others are a better approach, go for it: I’m certainly not stopping you.

Thirdly, questions about what it might do in the future and whether those things are a good idea:

The original conception I had for this in my head is now basically done. You can send commands to programs, you can tie programs together, you can get info out of a program and print it out. It would be able to do half the little scripty tasks I want to do on my desktop (assuming that the APIs existed to do them, which they mostly do not). Here are future things it could do, in rough order from small to big:

  1. Be cleverer about calling methods on applications with more than one object. At the moment you have to tell banshee's engine to pause, because Banshee exports more than one object. Since only one of those objects actually has a Pause() method, tell banshee to pause makes more sense.
  2. Have Linglish be able to document an application. ask linglish about tomboy which then prints out Tomboy commands you could use by introspecting Tomboy’s D-Bus API would be pretty nice. One big problem with this is that for most apps they need to be running to find out what API they offer, so ask linglish about banshee would start it up.
  3. There are currently no control statements. This is a problem if you want to do anything even semi-complicated in a script, especially since the common approach to D-Bus signals in Linux apps seems to be to generate a SomethingHasChanged and then pass a whatchanged parameter; Banshee fires StateChanged('paused') and StateChanged('playing') rather than Playing and Paused signals. NetworkManager has something similar. It’s understandable why: you get one signal in a few different flavours rather than a multitude of signals. Inconvenient for this, though, because to vary what the script does based on a parameter you have to have an if statement (or something similar). I’ve been thinking about this: I do not want to build a proper language. If you want that, learn Python. But…maybe it needs control statements. I don’t know. I’m against it, but if this is useless without them then that’s a strong argument that the effort is not worth it.
  4. A script editor. This would allow people to write scripts without having to know the names of any of the functions you need to call — popup completions and the like. This is even more problematic than ask linglish about whatever, since there’s no way of saying “which apps in the world offer a D-Bus API?” — most apps do not install an activation file, which means they must be running for any script editor to even know they exist. It’s also a lot of work, although most of the heavy lifting is done by GtkSourceView.
  5. Packaging and stuff. If this is likely to be useful I should make .debs of it and so on and make it easy for people to install and everything.

And finally…

The overarching question: is doing more of this a good idea and worth the effort? Your comments gratefully accepted.

More in the discussion (powered by webmentions)

  • (no mentions, yet.)