Launching URLs with awesome’s Run command

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.

One Thought on “Launching URLs with awesome’s Run command

Leave a Reply

Your email address will not be published. Required fields are marked *