├── .gitignore
├── LICENSE
├── README.md
├── autoload
├── graphql_client.vim
└── graphql_client
│ ├── curl.vim
│ ├── endpoint.vim
│ ├── output.vim
│ ├── request.vim
│ └── workspace.vim
├── doc
└── graphql-client-vim.jax
├── plugin
└── graphql_client.vim
├── syntax
└── gqlui.vim
└── test
└── test.graphql
/.gitignore:
--------------------------------------------------------------------------------
1 | /doc/tags*
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2023] [TakuroSugahara]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # graphql-client-vim
2 |
3 | This vim plugin provides graphql client features. Execute requests from a GraphQL file and immediately display the response.
4 |
5 |
6 |
7 |
8 | ## Usage
9 |
10 | - `:GraphQLClientExecute` current buffer (*.graphql) as graphql query.
11 |
12 | ## Installation
13 |
14 | dein
15 | ```dein.toml
16 | [[plugins]]
17 | repo = 'TakuroSugahara/graphql-client-vim'
18 | ```
19 |
20 | Neobundle
21 | ```
22 | NeoBundle 'TakuroSugahara/graphql-client-vim'
23 | ```
24 |
25 | Plug
26 | ```
27 | Plug 'jparise/vim-graphql'
28 | ```
29 |
30 | ### setting config
31 | ```vimL
32 | let g:graphql_client_headers = {
33 | \ 'authorization': 'Bearer your token here'
34 | \ }
35 | let g:graphql_client_endpoint = 'http://localhost:8080/api/graphql'
36 | ```
37 |
38 | ### Requirements
39 |
40 | - [curl](https://github.com/curl/curl)
41 |
42 | ### Want requirements
43 |
44 | - [jq](https://github.com/stedolan/jq)
45 | - Format a GraphQL response in JSON format.
46 |
47 | ### TODO
48 |
49 | - GraphQL schema parsing feature
50 | - Provides auto-completion and error detection capabilities.
51 |
--------------------------------------------------------------------------------
/autoload/graphql_client.vim:
--------------------------------------------------------------------------------
1 | let s:graphql_client = {}
2 | let s:graphql_client_instance = {}
3 |
4 | function! s:init() abort
5 | if empty(s:graphql_client_instance)
6 | let s:graphql_client_instance = s:graphql_client.new()
7 | endif
8 |
9 | return s:graphql_client_instance
10 | endfunction
11 |
12 | function! s:graphql_client.new() abort
13 | let s:graphql_client.curl = graphql_client#curl#new(g:graphql_client_headers)
14 | let s:graphql_client.request = graphql_client#request#new()
15 | let s:graphql_client.output = graphql_client#output#new()
16 | let s:graphql_client.endpoint = graphql_client#endpoint#new()
17 | let s:graphql_client.workspace = graphql_client#workspace#new(g:graphql_client_workspaces, s:graphql_client.curl)
18 | return s:graphql_client
19 | endfunction
20 |
21 | function! s:graphql_client.can_exec() abort
22 | let extension = expand('%:e')
23 | if extension != 'graphql'
24 | echoerr "Received *." .extension.". Please should execute *.graphql!"
25 | return 0
26 | endif
27 | return 1
28 | endfunction
29 |
30 | function! graphql_client#execute_request() abort
31 | call s:init()
32 |
33 | if !s:graphql_client.can_exec()
34 | return
35 | endif
36 |
37 | " 現在のファイルのfocusを記憶しておく
38 | let graphql_win_id = win_getid()
39 |
40 | let resp = s:graphql_client.curl.exec_graphql()
41 | call s:graphql_client.output.show()
42 | call s:graphql_client.output.write(split(resp, '\n'))
43 |
44 | call win_gotoid(graphql_win_id)
45 | endfunction
46 |
47 | function! graphql_client#open_ui() abort
48 | call s:init()
49 |
50 | " TODO: 分割表示がうまくいかないのでdadboduiを参考にする
51 | call s:graphql_client.endpoint.show()
52 | call s:graphql_client.request.show()
53 | call s:graphql_client.output.show()
54 | endfunction
55 |
56 | " function! graphql_client#open_endpoint() abort
57 | " call s:init()
58 | " call s:graphql_client.endpoint.show()
59 | " endfunction
60 |
61 | function! graphql_client#set_endpoint() abort
62 | call s:init()
63 | call s:graphql_client.endpoint.set_from_commandline()
64 | endfunction
65 |
66 | function! graphql_client#show_workspace() abort
67 | call s:init()
68 | call s:graphql_client.workspace.show()
69 | endfunction
70 |
71 |
--------------------------------------------------------------------------------
/autoload/graphql_client/curl.vim:
--------------------------------------------------------------------------------
1 | let s:curl = {}
2 |
3 | function! graphql_client#curl#new(headers) abort
4 | let s:curl = copy(s:curl)
5 | let s:curl.headers = a:headers
6 | return s:curl
7 | endfunction
8 |
9 | function! s:curl.set_headers(headers) abort
10 | let self.headers = a:headers
11 | endfunction
12 |
13 | function! s:curl.exec_graphql() abort
14 | let headers = self.generate_headers()
15 | let endpoint = self.generate_endpoint()
16 | let body = self.generate_body()
17 | let curl = self.build_curl(endpoint, headers, body)
18 | return system(curl)
19 | endfunction
20 |
21 | function! s:curl.generate_headers() abort
22 | let headers = ["-H 'Content-Type: application/json'"]
23 | for k in keys(self.headers)
24 | let h = "-H '" . k . ": " . self.headers[k] . "'"
25 | let headers = add(headers, h)
26 | endfor
27 | return headers
28 | endfunction
29 |
30 | function! s:curl.generate_endpoint() abort
31 | return g:graphql_client_endpoint
32 | endfunction
33 |
34 | function! s:curl.generate_body() abort
35 | let graphql_file = readfile(expand("%:p"))
36 | " bufnr("%")
37 | let query = join(graphql_file, "")
38 | "NOTE: 引数の文字列に対してエスケープしておかないとparaserがエラーになる"
39 | let query = substitute(query, "\"", '\\\"', 'g')
40 | return json_encode({"query": query})
41 | endfunction
42 |
43 | function! s:curl.build_curl(endpoint, headers, body) abort
44 | let header = join(a:headers)
45 |
46 | let curl = "curl -s -X POST %E %H -d '%B'"
47 | let curl = substitute(curl, "%E", a:endpoint, '')
48 | let curl = substitute(curl, "%H", header, '')
49 | return substitute(curl, "%B", a:body, '')
50 | endfunction
51 |
--------------------------------------------------------------------------------
/autoload/graphql_client/endpoint.vim:
--------------------------------------------------------------------------------
1 | let s:endpoint = {}
2 |
3 | function! graphql_client#endpoint#new() abort
4 | return s:endpoint.new()
5 | endfunction
6 |
7 | function! s:endpoint.new() abort
8 | let s:endpoint = copy(s:endpoint)
9 | let s:endpoint.buffer_name = 'graphql_client_endpoint'
10 | return s:endpoint
11 | endfunction
12 |
13 | function! s:endpoint.show() abort
14 | call self.open_buffer()
15 | call self.setup_buffer()
16 | endfunction
17 |
18 | function! s:endpoint.set_from_commandline() abort
19 | let input_endpoint = input('Graphql Endpoint URL: ')
20 | let g:graphql_client_endpoint = input_endpoint
21 | echo "Setting graphql endpoint: " . g:graphql_client_endpoint
22 | endfunction
23 |
24 | function! s:endpoint.open_buffer() abort
25 | let buffer_win = bufwinid(self.buffer_name)
26 | if buffer_win > -1
27 | call win_gotoid(buffer_win)
28 | else
29 | execute ":horizontal leftabove split " . self.buffer_name
30 | endif
31 | endfunction
32 |
33 | function! s:endpoint.setup_buffer() abort
34 | silent 1,$delete _
35 | call setline("1", g:graphql_client_endpoint)
36 | resize 2
37 | " setlocal buftype=nofile
38 | setlocal bufhidden=wipe
39 | setlocal noswapfile
40 | setlocal hidden
41 | endfunction
42 |
43 |
--------------------------------------------------------------------------------
/autoload/graphql_client/output.vim:
--------------------------------------------------------------------------------
1 | let s:output = {}
2 |
3 | function! graphql_client#output#new() abort
4 | return s:output.new()
5 | endfunction
6 |
7 | function! s:output.new() abort
8 | let s:output = copy(s:output)
9 | let s:output.buffer_name = 'output.json'
10 | let s:output.exist_jq = system('jq -h &> /dev/null && echo 0 || echo 1') == 0
11 | return s:output
12 | endfunction
13 |
14 | function! s:output.show() abort
15 | call self.open_buffer()
16 | call self.setup_buffer()
17 | endfunction
18 |
19 | function! s:output.write(strings) abort
20 | silent 1,$delete _
21 | call setline("1", a:strings)
22 |
23 | "---------- jqコマンドがあればformat ---------------"
24 | if self.exist_jq
25 | :%!jq '.'
26 | endif
27 | "---------- jqコマンドがあればformat ---------------"
28 | endfunction
29 |
30 | function! s:output.open_buffer() abort
31 | let buffer_win = bufwinid(self.buffer_name)
32 | if buffer_win > -1
33 | call win_gotoid(buffer_win)
34 | else
35 | execute "botright vnew " . self.buffer_name
36 | endif
37 | endfunction
38 |
39 | function! s:output.setup_buffer() abort
40 | setlocal buftype=nofile
41 | setlocal bufhidden=wipe
42 | setlocal noswapfile
43 | setlocal hidden
44 | endfunction
45 |
--------------------------------------------------------------------------------
/autoload/graphql_client/request.vim:
--------------------------------------------------------------------------------
1 | let s:request = {}
2 |
3 | function! graphql_client#request#new() abort
4 | return s:request.new()
5 | endfunction
6 |
7 | function! s:request.new() abort
8 | let s:request = copy(s:request)
9 | let s:request.buffer_name = 'request.graphql'
10 | return s:request
11 | endfunction
12 |
13 | function! s:request.show() abort
14 | call self.open_buffer()
15 | call self.setup_buffer()
16 | endfunction
17 |
18 | function! s:request.open_buffer() abort
19 | let buffer_win = bufwinid(self.buffer_name)
20 | if buffer_win > -1
21 | call win_gotoid(buffer_win)
22 | else
23 | " 現在のバッファと置き換えるようにバッファを作成
24 | " execute \":topleft vnew \" . self.buffer_name
25 | execute "e " . self.buffer_name
26 | endif
27 | endfunction
28 |
29 | function! s:request.setup_buffer() abort
30 | silent 1,$delete _
31 | setlocal buftype=nofile
32 | setlocal bufhidden=wipe
33 | setlocal noswapfile
34 | setlocal hidden
35 | endfunction
36 |
--------------------------------------------------------------------------------
/autoload/graphql_client/workspace.vim:
--------------------------------------------------------------------------------
1 | let s:workspace = {}
2 |
3 | function! graphql_client#workspace#new(workspaces, curl) abort
4 | return s:workspace.new(a:workspaces, a:curl)
5 | endfunction
6 |
7 | function! s:workspace.new(workspaces, curl) abort
8 | let s:workspace = copy(s:workspace)
9 | let s:workspace.buffer_name = 'gqlui'
10 | let s:workspace.workspaces = a:workspaces
11 | let s:workspace.curl = a:curl
12 | let s:workspace.current_workspace_key = len(a:workspaces) > 0 ? keys(a:workspaces)[0] : ''
13 | let s:workspace.icons = g:graphql_client_icons
14 | call s:workspace.set_current_workspace_from_key(s:workspace.current_workspace_key)
15 | return s:workspace
16 | endfunction
17 |
18 | function! s:workspace.show() abort
19 | call self.open_buffer()
20 | call self.setup_buffer()
21 | endfunction
22 |
23 | function! s:workspace.open_buffer() abort
24 | let buffer_win = bufwinid(self.buffer_name)
25 | if buffer_win > -1
26 | call win_gotoid(buffer_win)
27 | else
28 | execute "topleft vnew " . self.buffer_name
29 | endif
30 | endfunction
31 |
32 | function! s:workspace.setup_buffer() abort
33 | vertical-resize 40
34 | setlocal filetype=gqlui
35 | setlocal buftype=nofile
36 | setlocal bufhidden=wipe
37 | setlocal noswapfile
38 | setlocal hidden
39 |
40 | nnoremap :call method('set_current_workspace')
41 | nnoremap ? :call method('show_workspace_info')
42 |
43 | call self.redraw()
44 | setlocal nomodifiable
45 | endfunction
46 |
47 | function! s:workspace.redraw() abort
48 | setlocal modifiable
49 | " clear file
50 | silent 1,$delete _
51 |
52 | " write workspaces
53 | call setline(1, '" Press Enter for set endpoint')
54 | call setline(2, '')
55 |
56 | let i = 3
57 | for k in keys(self.workspaces)
58 | let workspace_name = k
59 | if self.current_workspace_key == k
60 | let workspace_name = k.' '.self.icons.current_workspace
61 | endif
62 | call setline(i, workspace_name)
63 |
64 | let i += 1
65 | endfor
66 |
67 | setlocal nomodifiable
68 | endfunction
69 |
70 | function! s:workspace.show_workspace_info() abort
71 | let content = matchstr(getline('.'), '\S\+')
72 | echo self.get_workspace_info(content)
73 | endfunction
74 |
75 | function! s:workspace.get_workspace_info(key) abort
76 | if !has_key(self.workspaces, a:key)
77 | return 'not found workspace info'
78 | endif
79 | return self.workspaces[a:key]
80 | endfunction
81 |
82 | function! s:workspace.set_current_workspace() abort
83 | let content = matchstr(getline('.'), '\S\+')
84 | call self.set_current_workspace_from_key(content)
85 | endfunction
86 |
87 | function! s:workspace.set_current_workspace_from_key(key) abort
88 | for k in keys(self.workspaces)
89 | if a:key == k
90 | let self.current_workspace_key = k
91 | let workspace_info = self.get_workspace_info(k)
92 | let g:graphql_client_endpoint = workspace_info.endpoint
93 | call self.curl.set_headers(workspace_info.headers)
94 |
95 | call self.redraw()
96 | echo 'set '.self.current_workspace_key.' workspace'
97 | return
98 | endif
99 | endfor
100 | endfunction
101 |
102 | function! s:method(method_name) abort
103 | return s:workspace[a:method_name]()
104 | endfunction
105 |
--------------------------------------------------------------------------------
/doc/graphql-client-vim.jax:
--------------------------------------------------------------------------------
1 | *graphql-client-vim.txt*
2 |
3 | GraphQL Client for https://github.com/TakuroSugahara/graphql-client-vim
4 |
5 | Author : TakuroSugahara
6 | License : MIT license {{{
7 | Permission is hereby granted, free of charge, to any person obtaining
8 | a copy of this software and associated documentation files (the
9 | "Software"), to deal in the Software without restriction, including
10 | without limitation the rights to use, copy, modify, merge, publish,
11 | distribute, sublicense, and/or sell copies of the Software, and to
12 | permit persons to whom the Software is furnished to do so, subject to
13 | the following conditions:
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | }}}
25 |
26 | ==============================================================================
27 | CONTENTS *graphql-client-vim-contents*
28 |
29 | INTRODUCTION |graphql-client-vim-introduction|
30 | USAGE |graphql-client-vim-usage|
31 | INTERFACE |graphql-client-vim-interface|
32 | VARIABLES |graphql-client-vim-variables|
33 | COMMANDS |graphql-client-vim-commands|
34 | FUNCTIONS |graphql-client-vim-functions|
35 | TODO |graphql-client-vim-todo|
36 | CHANGELOG |graphql-client-vim-changelog|
37 |
38 |
39 | ==============================================================================
40 | INTRODUCTION *graphql-client-vim-introduction*
41 |
42 | *graphql-client-vim.vim*provides graphql client features.
43 | Execute requests from a GraphQL file and immediately display the response.
44 |
45 | Latest version:
46 | https://github.com/user/graphql-client-vim.vim
47 |
48 |
49 | ==============================================================================
50 | USAGE *graphql-client-vim-usage*
51 |
52 |
53 |
54 | ==============================================================================
55 | INTERFACE *graphql-client-vim-interface*
56 |
57 | ------------------------------------------------------------------------------
58 | VARIABLES *graphql-client-vim-variables*
59 |
60 | g:graphql_client_endpoint *g:graphql_client_endpoint*
61 | Default value: ""
62 |
63 |
64 | g:graphql_client_headers *g:graphql_client_headers*
65 | Default value: {}
66 |
67 |
68 | ------------------------------------------------------------------------------
69 | COMMANDS *graphql-client-vim-commands*
70 |
71 | :GraphQLClientExecute *:GraphQLClientExecute*
72 | current buffer (*.graphql) as graphql query.
73 |
74 | ------------------------------------------------------------------------------
75 | FUNCTIONS *graphql-client-vim-functions*
76 |
77 | ==============================================================================
78 | TODO *graphql-client-vim-todo*
79 |
80 |
81 | ==============================================================================
82 | CHANGELOG *graphql-client-vim-changelog*
83 |
84 |
85 | ==============================================================================
86 | vim:tw=78:ts=8:ft=help:norl:noet:fen:
87 |
--------------------------------------------------------------------------------
/plugin/graphql_client.vim:
--------------------------------------------------------------------------------
1 | if exists("g:loaded_graphql_client")
2 | finish
3 | endif
4 | let g:loaded_graphql_client = 1
5 |
6 | let g:graphql_client_endpoint = get(g:, 'graphql_client_endpoint', '')
7 | let g:graphql_client_workspaces = get(g:, 'graphql_client_workspaces', {})
8 | let g:graphql_client_headers = get(g:, 'graphql_client_headers', {})
9 | let g:graphql_client_headers = get(g:, 'graphql_client_headers', {})
10 | let g:graphql_client_icons = get(g:, 'graphql_client_icons', {
11 | \ 'current_workspace': '✓'
12 | \})
13 |
14 | augroup GraphqlClient
15 | autocmd!
16 | autocmd FileType gqlui autocmd BufEnter,WinEnter stopinsert
17 | augroup END
18 |
19 | " Execute graphql request
20 | command! -nargs=0 GQLExecute call graphql_client#execute_request()
21 | " Set endpoint url
22 | command! -nargs=0 GQLSetEndpoint call graphql_client#set_endpoint()
23 | " Show graphql workspace
24 | command! -nargs=0 GQLShowWorkSpace call graphql_client#show_workspace()
25 |
26 |
--------------------------------------------------------------------------------
/syntax/gqlui.vim:
--------------------------------------------------------------------------------
1 | syntax clear
2 |
3 | exe 'syn match gqlui_current_workspace /'.g:graphql_client_icons.current_workspace.'/'
4 | syn match graphql_client_comment /^".*$/
5 | hi default link graphql_client_comment Comment
6 | if &background ==? 'light'
7 | hi gqlui_current_workspace guifg=#00AA00
8 | else
9 | hi gqlui_current_workspace guifg=#88FF88
10 | endif
11 |
12 |
--------------------------------------------------------------------------------
/test/test.graphql:
--------------------------------------------------------------------------------
1 | query findOneUser {
2 | user(id: "user-1") {
3 | id
4 | name
5 | createdAt
6 | updatedAt
7 | }
8 | }
9 |
--------------------------------------------------------------------------------