Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support field autocompletion by GraphQL introspection #2

Open
davazp opened this issue Oct 15, 2016 · 21 comments
Open

Support field autocompletion by GraphQL introspection #2

davazp opened this issue Oct 15, 2016 · 21 comments
Labels

Comments

@davazp
Copy link
Owner

davazp commented Oct 15, 2016

Using GraphQL introspection we can get the fields, what could be used to autocomplete the fields at point.

@davazp davazp added the feature label Oct 15, 2016
@timoweave
Copy link
Collaborator

Hey David,
Which completion package (auto-complete, company, or any) are you going to use?
Thanks for your time

@davazp
Copy link
Owner Author

davazp commented Sep 12, 2017

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.

@timoweave
Copy link
Collaborator

I am new to completion (ac, company, helm, ...).
Is any the same thing as helm (anything.el) that you are referring?

@davazp
Copy link
Owner Author

davazp commented Sep 12, 2017

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.

@timoweave
Copy link
Collaborator

I am not familiar with completion either. Are we referring

  1. keywords only completion (static) or
  2. user field and user type, query, mutation, fragment, variables (dynamic),

@davazp
Copy link
Owner Author

davazp commented Sep 12, 2017

I was thinking mostly about fields, specially useful for queries.

But the more the better. We have to start somewhere.

@timoweave
Copy link
Collaborator

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.

@timoweave
Copy link
Collaborator

timoweave commented Sep 28, 2017

would these introspection good enough for fields?

query get_schema_info {
  __schema {
    types {
      name
      fields {
        name
        type {
          name
          kind
          ofType {name}
        }
      }
    }
  }
}

@davazp
Copy link
Owner Author

davazp commented Sep 28, 2017

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 :-)

@timoweave
Copy link
Collaborator

Yeah, we need a proper parser.

  1. that parser can parse the query file, the __schema type buffer (from server),
    which we resolve the type back into graphql file.
  2. 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.
  3. so that and turn that whatever syntax tree into child-type field lookup table with
    the parent-type field.
  4. 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?

  1. c/c++ lex/yacc parser/codgen that bind it to elisp?
  2. all elisp parser/codegen, similar to js2-mode?

@davazp
Copy link
Owner Author

davazp commented Sep 29, 2017

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.

@timoweave
Copy link
Collaborator

timoweave commented Oct 2, 2017

  1. first dynamic and context sensitive completion with query.

screen shot 2017-10-02 at 12 59 18 am

@davazp
Copy link
Owner Author

davazp commented Oct 2, 2017

Looks awesome. Is it using introspection then?

@timoweave
Copy link
Collaborator

timoweave commented Oct 3, 2017

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.

out2

@timoweave
Copy link
Collaborator

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.

@davazp
Copy link
Owner Author

davazp commented Oct 3, 2017

I will try if I have some time.

@danrasmuson
Copy link

This looks awesome. Would love an update on where this stands.

@davazp
Copy link
Owner Author

davazp commented Jan 15, 2018

@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. 👍

@timoweave
Copy link
Collaborator

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.

@viniciussbs
Copy link

Hi, folks! Any update on this? I've tried company-graphql but it's not on MELPA, @timoweave.

@TOTBWF
Copy link
Contributor

TOTBWF commented Oct 16, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants