graphql-mode
graphql-mode copied to clipboard
Support field autocompletion by GraphQL introspection
Using GraphQL introspection we can get the fields, what could be used to autocomplete the fields at point.
Hey David, Which completion package (auto-complete, company, or any) are you going to use? Thanks for your time
Hopefully any. I would do a basic integration with the built-in mechanism of Emacs, so hopefully all the fancy packages can work on top of it.
I am new to completion (ac, company, helm, ...). Is any the same thing as helm (anything.el) that you are referring?
I'm not fully familiar with completion either, but this link
https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html
this the relevant standard way to implement completion in-buffers in Emacs.
The packages you mention ac,company,helm are able to read this normally, so every standard completion in emacs work for them. Although they then extend that with more custom functionality.
I would like to support first the standard emacs functionality I mentioned, and then optionally and if it is worthy, we can support other extensions.
I am not familiar with completion either. Are we referring
- keywords only completion (static) or
- user field and user type, query, mutation, fragment, variables (dynamic),
I was thinking mostly about fields, specially useful for queries.
But the more the better. We have to start somewhere.
Yeah, you are right: start with the first standard and then extend later on. I need to read/experiment a bit more about completion to get some idea how to develop this feature.
would these introspection good enough for fields?
query get_schema_info {
__schema {
types {
name
fields {
name
type {
name
kind
ofType {name}
}
}
}
}
}
I am not sure right now.
I looks like it. I guess it's a bit trickier to "parse" the query, so we have a path field1 > field2 > ... and we can infer the type at that point. But it should work :-)
Yeah, we need a proper parser.
- that parser can parse the query file, the __schema type buffer (from server),
which we resolve the type back into graphql file. - then we use graphql schema language as intermedia language as well, and we
can treat query or type buffer the same to create lookup table. - so that and turn that whatever syntax tree into child-type field lookup table with
the parent-type field. - also take care of the sytnax. for example if one split "query hello {...}" into "query\n hello\n {...}"
the "query", "hello" would pick up the syntax color as in one-liner.
Do you have any recommendation about how to approach the parser?
- c/c++ lex/yacc parser/codgen that bind it to elisp?
- all elisp parser/codegen, similar to js2-mode?
I don't think we actually need a full parser. It's quite easy to go upward in the elisp parser state levels . ({}). For example
query {
alias: field1 () {
alias2: field2 () {
|
}
}
}
going upward in the sexprs would take us to the parent fields, so we only need to find the field name (not alias), by skipping over the parenthesis and reading a word.
However, having a full parser would be probably great for other functionality. If you want, we can go in that direction. We can write our own parser, using any of the well known techniques, or we can try to translate the official parser from js to elisp more literally.
- first dynamic and context sensitive completion with
query.
Looks awesome. Is it using introspection then?
Yeah, the completion use introspection, whatever the __schema response from the server. Right now, I just save the __schema response to a file, hook up the algorithm, and get draft going. That __Schema is not very useful. Instead, I extend root ("") that make it easier to lookup scope.
Here is the 2nd draft, a separated package company-graphql.el.

I wrote few parsers in the past. It is not hard in C/C++, or python, but I am not sure in elisp.... but elisp is an excellent language to handle recursive parser itself without grammar... For now, I will put this parser idea on the side... and get other stuff going.
I will try if I have some time.
This looks awesome. Would love an update on where this stands.
@timoweave do you have any update of this? or can you share a branch with your changes? perhaps we can merge a initial version and leave the proper parsing for later. 👍
Yeah, David!
We have new participant!
It will be really fully functional like graphiql-mode using language server, for completion, indentation, and color (the last two was not part of the Microsoft language server spec)
Interested in working on it together? I’ve also like good peer like David, good cider, to keep my motivation going.
Hi, folks! Any update on this? I've tried company-graphql but it's not on MELPA, @timoweave.
With graphql-language-service and lsp-mode, you can get auto-completion with this snippet:
(lsp-register-client
(make-lsp-client :new-connection (lsp-tcp-connection (lambda (port) `("graphql" "server" "-m" "socket" "-p" ,(number-to-string port))))
:major-modes '(graphql-mode)
:initialization-options (lambda () `())
:server-id 'graphql))
(add-to-list 'lsp-language-id-configuration '(graphql-mode . "graphql"))
I'll look in to getting this upstreamed into lsp-mode.