A SPARQL mode for emacs
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


What is it?

A major mode for emacs that provides syntax highlighting for SPARQL. It also provides a way to execute queries against a SPARQL HTTP endpoint, such as is provided by Fuseki. It is also possible to query other endpoints like DBPedia.

Getting Started

https://melpa.org/packages/sparql-mode-badge.svg https://stable.melpa.org/packages/sparql-mode-badge.svg

  • Download sparql-mode and put it in a directory somewhere.
  • Add the following to your .emacs file
(add-to-list 'load-path "/path/to/sparql-mode-dir")
(autoload 'sparql-mode "sparql-mode.el"
    "Major mode for editing SPARQL files" t)
(add-to-list 'auto-mode-alist '("\\.sparql$" . sparql-mode))
(add-to-list 'auto-mode-alist '("\\.rq$" . sparql-mode))

Now sparql-mode will load whenever you visit a file whose name ends with .sparql. Alternatively, run M-x sparql-mode in an existing buffer containing SPARQL commands.

It is also possible to add

-*- mode: sparql -*-

to the top of the file. This is a comment read by emacs to discover what mode to use.

Auto complete

SPARQL-mode has basic support for both auto-complete-mode and company-mode. Just add your favourite completion mode to sparql-mode-hook.

(add-hook 'sparql-mode-hook 'your-favourite-completion-mode)

Executing SPARQL Queries from within Emacs

From a buffer that is in sparql-mode, execute M-x sparql-query-region. You will be prompted for a SPARQL HTTP endpoint in the minibuffer, which defaults to http://localhost:2020/. Once set, it will be used for all subsequent queries in that buffer. Results will be displayed in another buffer in CSV format.

Org-babel support

It is also possible to use sparql-mode with org-mode and executing queries with org-babel. You can do that by adding the following snippet or adding (sparql . t) to languages org-babel can load:

 '((sparql . t)))

You can then execute the query by pressing C-c C-c on the source-block header.

By default results formatted as text/csv will be converted to an org table. This can be disabled by adding :results scalar to the header. See examples.


Default behaviour for results in csv is to convert the result to a table:

#+BEGIN_SRC sparql :url http://live.dbpedia.org/sparql :format text/csv
    [] a ?Concept
  } LIMIT 5

| Concept                                                          |
| http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat          |
| http://www.openlinksw.com/schemas/virtrdf#QuadStorage            |
| http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat |
| http://www.openlinksw.com/schemas/virtrdf#QuadMap                |
| http://www.openlinksw.com/schemas/virtrdf#QuadMapValue           |

If you don’t want to convert the result to a table, you can override that behaviour by specifying that the result should be scalar:

#+HEADER: :url http://live.dbpedia.org/sparql
#+HEADER: :format text/csv
#+HEADER: :results scalar
#+BEGIN_SRC sparql
    [] a ?Concept
  } LIMIT 5

: "Concept"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat"
: "http://www.openlinksw.com/schemas/virtrdf#QuadStorage"
: "http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMap"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMapValue"

We can also declare variables that will then be expanded before execution. For example the following query:

  ?x foaf:name ?name.
  $x foaf:email ?email.

will be transformed into the following before it is executed:

  friend:Julia foaf:name ?name.
  friend:Julia foaf:email ?email.

Notice that $x and ?x are treated as identical. This is because SPARQL treats them as identical.

By combining this with the #+call syntax we can create and reuse queries:

#+NAME: count-statements-in-graph
#+BEGIN_SRC sparql :var graph="<>"
  SELECT (COUNT(*) AS ?count) WHERE {
    GRAPH $graph {
      ?s ?p ?o .

#+CALL: count-statements-in-graph("<http://example.com/my-graph>")

| count |
|  1001 |

#+CALL: count-statements-in-graph("<http://example.com/my-other-graph>")

| count |
|   100 |

Notice that the server request is done synchronously and will therefore lock the editor if the request takes a long time.

Bugs and Enhancements

If you have a problem or would like to see it get better in a specific way, feel free to drop an issue in the issue tracker. Enjoy!