Posted Tuesday, 22-May-2012 by Ingo Karkat; last update Thursday, 14-Mar-2013
For keyboard centric power users like me, the Pentadactyl Firefox add-on brings modal editing and Vim-inspired key bindings to the Firefox browser. Even better, you can quickly edit any text field in Vim by pressing Ctrl + I. I use this for anything longer than a couple of words: Wiki edits, GitHub comments, Stack Overflow answers, etc.
Now, even though I have implemented some crude detection of various markups (Markdown, MediaWiki, Textile) inside Vim, wouldn't it be nice if the filetype could be derived automatically from the URL of the page I'm currently editing? Saving a manual :setf markdown on each launch, I would be able to enjoy the correct syntax highlighting from the start, even when triggering the external edit from a blank edit field.
Pentadactyl supports macros like <line> and <column>, but there is no such thing as <url> or <hostname>. (And even if it could be passed to Vim, it would still need to be translated into a filetype inside Vim.) But it is possible to hook into the triggering of the external editor via an Input mode mapping:
Inoremap <C-i> -javascript editExternallyWithFiletype()
Inside the JavaScript implementation of the mapping, we try to determine a filetype, and append this temporarily to the 'editor' setting. The filetype is passed to Vim via a +setf filetype command-line argument. Then the external editor is triggered by invoking the internal Pentadactyl function, and the setting is restored.
Update 14-Mar-2013: Just appending the +setf doesn't work when (like in the default option value) there's already a +cmd. I've extended the code to handle this.
javascript <<EOF function editExternallyWithFiletype() { var save_editor = options["editor"]; var filetype = editExternallyFiletype();if (filetype) { options["editor"] += " \"+setf " + filetype + "\""; }// Insert the :setf command before any existing +cmd, as there can be only one such argument. options["editor"] = options["editor"].replace(/ "\+/, " \"+setf " + filetype + "|") if (options["editor"] == save_editor) { // The 'editor' setting doesn't yet contain a passed +cmd; append it. options["editor"] += " \"+setf " + filetype + "\""; } editor.editFieldExternally(); options["editor"] = save_editor; } EOF
For determining the filetype, we can test the properties of the Pentadactyl buffer.URL object for matching sites. This is the part that you have to adapt to the sites that you frequent, and to the Vim syntax definitions that you have installed (you can find many on vim.org). Here's an example:
javascript <<EOF function editExternallyFiletype() { var host = buffer.URL.host switch(host.replace(/^www\./, "")) { case "github.com": if (! buffer.URL.path.match("/wiki/")) return "markdown"; case "reddit.com": return "markdown"; case "stackoverflow.com": return "markdown"; } if (host.match(/.*\.wikia\.com$/) || host.match(/.*\.wikipedia\.org$/)) return "mediawiki"; } EOF
Put all of the above into your ~/.pentadactylrc configuration, and enjoy the enhanced, intelligent editing of web page forms with all the amenities of Vim's filetype mechanism1!
Ingo Karkat, 22-May-2012
ingo's blog is licensed under Attribution-ShareAlike 4.0 International
blog comments powered by Disqus