Posted 2010-11-26T14:00:00+01:00 in web

VIM XQuery syntax file

Improved syntax highlighting and comment folding on XQuery code in the VIM editor

Get the syntax file at: http://github.com/jeroenp/vim-xquery-syntax

This syntax file has been used while working on a 2000+ lines project with numerous modules where I found that the xquery syntax that currently comes with VIM didn’t work. This syntax file is by no means complete, but I think that it’s good enough to release.

I try to stay close to the way VIM does C syntax highlighting; For variable names I use the \k character class for keywords, which may not correspond to the XQuery specification but in practice this will be what most people will want to use.

This syntax file differs from Jean-Marc Vanel’s syntax file in that it doesn’t use the XML syntax as a base. I find the XML highlighting distracting when programming; Since you’re only working with snippets of XML at a time, I don’t think the XML highlighting helps. Instead, the code structure is highlighted. It’s easy to spot variable references inside XML literals this way, for example.

Example

Here’s a sample what the highlighting looks like with a sample piece of code from Norman Walsh’s Flickr library:

xquery version "1.0-ml";

module namespace flickr="http://www.flickr.com/services/api/";

declare default function namespace "http://www.w3.org/2005/xpath-functions";

declare option xdmp:mapping "false";

declare variable $key    := "YOUR API KEY";
declare variable $secret := "YOUR API SECRET";
declare variable $token  := "YOUR AUTH_TOKEN";

declare function flickr:_flickr-pages(
    $method as element(flickr:method),
    $result as element()?)
{
  let $args := for $arg in ($method/flickr:arg,
                            <flickr:arg name="api_key">{$key}</flickr:arg>,
                            if ($method/@auth="true")
                            then
                              <flickr:arg name="auth_token">{$token}</flickr:arg>
                            else
                              (),
                            <flickr:arg name="method">{string($method/@name)}</flickr:arg>)
               order by $arg/@name ascending
               return $arg
  let $sign := string-join(($secret, for $arg in $args return concat($arg/@name,$arg)), "")
  let $md5  := xdmp:md5($sign)
  let $uri  := concat("http://api.flickr.com/services/rest/?method=", $method/@name,
                      "&amp;api_key=", $key, "&amp;",
                      string-join(for $arg in $method/flickr:arg
                                  return concat($arg/@name, "=", string($arg)), "&amp;"),
                      if ($method/@auth="true")
                      then concat("&amp;auth_token=", $token)
                      else "",
                      "&amp;api_sig=", $md5)
  let $rsp  := xdmp:http-get($uri)
  return
    if ($rsp[2]/*/@stat = "ok")
    then
      let $body  := $rsp[2]/*/*
      let $page  := if ($body/@page and $body/@page castable as xs:integer)
                    then xs:integer($body/@page)
                    else 0
      let $pages := if ($body/@pages and $body/@pages castable as xs:integer)
                    then xs:integer($body/@pages)
                    else 0
      let $new   := if (empty($result))
                    then $body
                    else element { node-name($result) } { $body/@*, $result/*, $body/* }
      return
        if ($page < $pages and (not($method/flickr:arg[@name="page"]) or not(empty($result))))
        then
          let $newmethod := element { node-name($method) }
                                    { $method/@*, $method/*[not(@name='page')],
                                      <flickr:arg name="page">{$page + 1 }</flickr:arg>
                                    }
          return
            flickr:_flickr-pages($newmethod, $new)
        else
          flickr:_fixns($new)
    else
      <flickr:error>{$rsp}</flickr:error>
};