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() 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:
- 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 pausemakes more sense.
- Have Linglish be able to document an application.
ask linglish about tomboywhich 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 bansheewould start it up.
- 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
SomethingHasChangedand then pass a
whatchangedparameter; Banshee fires
Pausedsignals. 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
ifstatement (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.
- 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.
- 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.
The overarching question: is doing more of this a good idea and worth the effort? Your comments gratefully accepted.