Following on the heels of my google search hotkey in awesome, I decided to tackle expanding the functionality of the run prompt. Awesome’s run prompt, by default, is basically a command-launcher; it chokes on any input that doesn’t represent an executable file.
I wanted it to behave more like the run prompt in other desktops, so that typing in a URL would open the URL in an appropriate application.
With help from Alexander Yakushev on the awesome mailing list, I managed to figure it out….
I originally had planned to just send any identified URL to xdg-open, but I found that it really only handles file, http, and ftp urls properly. More exotic urls, like ssh://, fish://, smb://, vnc://, man://, and others require more explicit direction. So the first thing was to define which programs would handle various protocols, using a lua table:
--runners for various protocols myrunners = { http = "xdg-open", ftp = "dolphin", file = "xdg-open", vnc = "krdc", rdp = "krdc", fish = "dolphin", smb = "dolphin", man = "dolphin", info = "dolphin" } |
The next step was to override the default run callback. This takes place down in the globalkeys assignment table, where the default file has something like this:
awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end), |
I replaced it with this definition:
awful.key({ modkey }, "r", function () local promptbox = mypromptbox[mouse.screen] awful.prompt.run( {prompt = "<span>Run: </span>"}, promptbox.widget, function (command) local protocol = command:match("^(%a+):/+") if protocol then command = (myrunners[protocol] or "xdg-open").." " .. command end local result = awful.util.spawn(command) if type(result) == "string" then promptbox.widget.text = result end end, awful.completion.shell, awful.util.getdir("cache") .. "/history") end), |
My callback for the run command (starting on line 6 here) basically does this:
- Uses a regex to search for the string “:/” as part of the first word, and puts the letters before the colon into a variable called “protocol”
- If there is a protocol, it looks up the protocol in the “myrunners” table, and prepends the resulting command (or xdg-open, if the protocol isn’t in the table) to the URL.
- If there isn’t a protocol found (the first word contains no “:/”), then it does nothing
- Finally, the constructed command is run!
It works great, and allows me to quickly open remote URLs with a minimum of fuss. So far the only shortcoming is that opening files this way requires using “file://” followed by the full path. I’m contemplating the best way to streamline opening files in awesome, but haven’t quite decided how I want to work with it yet.
Awesome! Thank you!