New GraphQL Sourcegraph extension

Chris Wendt
December 5, 2018

ourcegraph extensions make it easy to build code intelligence using existing language analysis tools that don't necessarily speak LSP (the Language Server Protocol).

GraphQL is one of these languages that has a language analysis tool and I spent a few days building a Sourcegraph extension for it.

You can try it out on Sourcegraph.com by first enabling the GraphQL extension then visiting a sample GraphQL file (beware this is relatively experimental - only hover tooltips and jump-to-definition within the same file work).

image

The first step was to start with the activate() function that will run when the Sourcegraph extension is run:

export function activate(): void {}

Then I grab the address of the GraphQL language server from a user setting:

export function activate(): void {+  const address = sourcegraph.configuration.get<Settings>().get('graphql.langserver-address') }

Then I register a callback that will run when the user hovers over something in a GraphQL file:

    
 export function activate(): void {
   const address = sourcegraph.configuration.get().get('graphql.langserver-address')
 
+  sourcegraph.languages.registerHoverProvider([{ pattern: '*.{graphql,gql}'}], {
+    provideHover: async (doc, pos) => {
+        return ajax({
+            method: 'POST',
+            url: address,
+            body: JSON.stringify({ method: 'hover', doc, pos }),
+            responseType: 'json',
+            headers: {
+                'Content-Type': 'application/json',
+            },
+        })
+    }
+  })
 }
    
    

It sends a request to a https://github.com/chrismwendt/graphql-ws-langserver running elsewhere.

Then I convert the response to something that the Sourcegraph extension API understands (with Python syntax highlighting to recognize comment lines starting with #)

    
 export function activate(): void {
   const address = sourcegraph.configuration.get().get('graphql.langserver-address')
 
   sourcegraph.languages.registerHoverProvider(docSelector, {
     ...
   })
+    .then(response => {
+        return (
+            response &&
+            response.response &&
+            response.response.contents && {
+                contents: {
+                    // python syntax highlighting works pretty well for GraphQL
+                    value: '```python\n' + response.response.contents.join('\n') + '\n```',
+                    kind: sourcegraph.MarkupKind.Markdown,
+                },
+            }
+        )
+    })
 }
 
   
    

Check out the repository for the extension and the server component.

Subscribe for the latest code AI news and product updates

By submitting, I agree to Sourcegraph's Terms of Service and Privacy Policy.

Ready to accelerate
how you build software?

Use Sourcegraph to industrialize your software development

Get started
Book a demo