module: add :lang graphql

This module enables GraphQL[1] usage within Doom with extended
functionality.

[1] https://www.graphql.org
This commit is contained in:
Ellis Kenyő 2022-03-31 08:28:43 +01:00 committed by Henrik Lissner
parent e8c22c770b
commit 4da450ffd7
6 changed files with 178 additions and 0 deletions

View file

@ -134,6 +134,7 @@
;;fstar ; (dependent) types and (monadic) effects and Z3 ;;fstar ; (dependent) types and (monadic) effects and Z3
;;gdscript ; the language you waited for ;;gdscript ; the language you waited for
;;(go +lsp) ; the hipster dialect ;;(go +lsp) ; the hipster dialect
;;(graphql +lsp) ; Give queries a REST
;;(haskell +lsp) ; a language that's lazier than I am ;;(haskell +lsp) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python ;;hy ; readability of scheme w/ speed of python
;;idris ; a language you can depend on ;;idris ; a language you can depend on

View file

@ -0,0 +1,115 @@
#+TITLE: lang/graphql
#+DATE: March 31, 2022
#+SINCE: v2.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#sending-queries][Sending queries]]
- [[#viewing-docs][Viewing docs]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds [[https://www.graphql.org][GraphQL]] support to Doom Emacs.
+ Code completion
+ LSP support (=+lsp=)
+ Diagnostics (GraphQL syntax linting/validations) (spec-compliant)
+ Autocomplete suggestions (spec-compliant)
+ Hyperlink to fragment definitions and named types (type, input, enum) definitions (spec-compliant)
+ Outline view support for queries and SDL
+ Symbols support across the workspace
+ Local schema viewer
+ Org-babel exporter (requires =:lang org=)
** Maintainers
+ [[https://github.com/elken][@elken]] (Author)
** Module Flags
+ =+lsp= Enable LSP support through [[https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli#readme][graphql-language-service-cli]] (also requires =:tools lsp=)
** Plugins
+ [[https://github.com/davazp/graphql-mode][graphql-mode]]
+ [[https://github.com/ifitzpatrick/graphql-doc.el][graphql-doc]]
+ [[https://github.com/timoweave/company-graphql][company-graphql]] (when =+lsp= is disabled)
** Hacks
Added a convenience function =+graphql-doc-open-config= to open schema docs from a
[[https://github.com/jimkyndemeyer/graphql-config-examples][=.graphqlconfig=]] file.
* Prerequisites
There are no prerequisites for using this module. LSP server should be
downloaded upon opening a graphql buffer.
* Features
** Sending queries
When visiting a graphql buffer, you have access to the ability to send the
current query with =C-c C-c= which will prompt you for an optional variables file,
then execute the query and return a buffer of the results.
It's also possible to send queries using org-babel using a block such as the
ones below (executing correctly will require =:lang org=)
#+NAME: my-variables
#+begin_src json
{
"continentCode": "AF"
}
#+end_src
#+BEGIN_SRC graphql :url https://countries.trevorblades.com/ :variables my-variables
query GetContinents($continentCode: String!) {
continent(code: $continentCode) {
name
code
}
}
#+END_SRC
#+RESULTS:
: {
: "data": {
: "continent": {
: "name": "Africa",
: "code": "AF"
: }
: }
: }
** Viewing docs
With this module, there are 3 ways to view schemas:
+ =+graphql-doc-open-config= which uses a local [[https://github.com/jimkyndemeyer/graphql-config-examples][=.graphqlconfig=]] file to seed endpoints to query
+ =graphql-doc= which prompts you to select an endpoint based on ones added manually by =graphql-doc-add-api=
+ =graphql-doc-open-url= which prompts to to manually enter an endpoint url
When using the doc viewer, there are a few bindings for navigating around.
| Key | Command | Description |
|-------------+---------------------+-----------------------------------|
| =C-j= | =forward-button= | Follow a forward button |
| =C-k= | =backward-button= | Follow a backward button |
| =<backspace>= | =graphql-doc-go-back= | Go back to a previous page |
| =mouse-1= | - | Follow the next label under =point= |
| =RET= | - | Follow the next label under =point= |
* Configuration
Most of the "magic" in the module relies on a properly configured
[[https://github.com/jimkyndemeyer/graphql-config-examples][=.graphqlconfig=]] file, so follow the examples linked to create an appropriate
setup.
LSP configuration is handled through [[https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli#graphql-configuration-file-graphqlrcyml][GraphQL Config]] to handle custom directives/documents/validation etc.
These files will also be useful to other editors, so it would be worth trying to
get them into version control.
* Troubleshooting
- [[https://github.com/ifitzpatrick/graphql-doc.el/issues][Issues with the doc viewer]]
- [[https://github.com/davazp/graphql-mode/issues][Issues with graphql-mode]]
- [[https://github.com/emacs-lsp/lsp-mode/issues][Issues with LSP]] ([[https://github.com/graphql/graphiql/issues][Upstream LSP issues]])

View file

@ -0,0 +1,14 @@
;;; lang/graphql/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +graphql-doc-open-config ()
"Locate a .graphqlconfig file in the current tree and use that to point to a
schema."
(interactive)
(let ((config (json-read-file (graphql-locate-config "."))))
(let-alist config
(if-let ((endpoints .extensions.endpoints)
(endpoint (cdr (assq (intern (graphql--completing-read-endpoint endpoints)) endpoints))))
(let-alist endpoint
(graphql-doc--start .url `(:url ,.url :headers ,.headers)))
(error "No endpoint configurations in .graphqlconfig")))))

View file

@ -0,0 +1,39 @@
;;; lang/graphql/config.el -*- lexical-binding: t; -*-
(after! graphql-mode
(defface all-the-icons-rhodamine
'((t (:foreground "#E10098")))
"Face for GraphQL icon."
:group 'all-the-icons-faces)
;; Define a doom-modeline compatiable major-mode icon
(after! all-the-icons
(setf (alist-get "graphql" all-the-icons-extension-icon-alist)
'(all-the-icons-fileicon "graphql" :v-adjust -0.05 :face 'all-the-icons-rhodamine))
(setf (alist-get "gql" all-the-icons-extension-icon-alist)
'(all-the-icons-fileicon "graphql" :v-adjust -0.05 :face 'all-the-icons-rhodamine))
(setf (alist-get 'graphql-mode all-the-icons-mode-icon-alist)
'(all-the-icons-fileicon "graphql" :v-adjust -0.05 :face 'all-the-icons-rhodamine)))
(if (featurep! +lsp)
(add-hook 'graphql-mode-local-vars-hook #'lsp! 'append)
(set-company-backend! 'graphql-mode 'company-graphql))
(add-hook 'graphql-mode-hook #'rainbow-delimiters-mode)
(set-docsets! 'graphql-mode :add "GraphQL Specification")
(set-electric! 'graphql-mode
:chars '(?\} ?\))
:words '("or" "and"))
(set-ligatures! 'graphql-mode
:null "null"
:true "true" :false "false"
:int "Int" :str "String"
:float "Float"
:bool "Bool"
:not "not"
:and "and" :or "or"))
(use-package! graphql-doc
:after graphql-mode)

View file

@ -0,0 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; lang/graphql/packages.el
(package! graphql-mode :pin "9740e4027bd9313697d5cac5caaa5b15626ab1da")
(package! graphql-doc :pin "6ba7961fc9c5c9818bd60abce6ba9dfef2dad452")
(when (not (featurep! +lsp))
(package! company-graphql :pin "757dfa45ad0cef9b9c362c8993d6474a2426c01c"))

View file

@ -103,6 +103,8 @@
(package! ob-elixir :pin "8990a8178b2f7bd93504a9ab136622aab6e82e32")) (package! ob-elixir :pin "8990a8178b2f7bd93504a9ab136622aab6e82e32"))
(when (featurep! :lang go) (when (featurep! :lang go)
(package! ob-go :pin "2067ed55f4c1d33a43cb3f6948609d240a8915f5")) (package! ob-go :pin "2067ed55f4c1d33a43cb3f6948609d240a8915f5"))
(when (featurep! :lang graphql)
(package! ob-graphql :pin "7c35419f9eec5dc44967cbcfa13c7135b9a96bfc"))
(when (featurep! :lang hy) (when (featurep! :lang hy)
(package! ob-hy :pin "a42ecaf440adc03e279afe43ee5ef6093ddd542a")) (package! ob-hy :pin "a42ecaf440adc03e279afe43ee5ef6093ddd542a"))
(when (featurep! :lang nim) (when (featurep! :lang nim)