aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Clason <c.clason@uni-graz.at>2024-12-23 11:12:58 +0100
committerChristian Clason <ch.clason+github@icloud.com>2024-12-23 11:34:23 +0100
commitadcd9360dfefc7b1e1edb0e86df460e074991c8d (patch)
tree85ed4ecb564b53650561576f124d4c155a267251
parent7e1c1ff7fcf2cbc564c90a656124b70ad8bb4d5f (diff)
downloadrneovim-adcd9360dfefc7b1e1edb0e86df460e074991c8d.tar.gz
rneovim-adcd9360dfefc7b1e1edb0e86df460e074991c8d.tar.bz2
rneovim-adcd9360dfefc7b1e1edb0e86df460e074991c8d.zip
vim-patch:4ce1cb5: runtime(graphql): contribute vim-graphql to Vim core
Contribute the core of my vim-graphql project (ftplugin, indent, syntax) to the Vim project. This replaces the basic ftplugin support that was already in the runtime with a more complete set of filetype settings. I can assume maintainership for all of these files. I'll continue to maintain the higher-level embedded filetype support separately (in vim-graphql) for now, because it's fairly complex, but we can consider integrating that code directly into vim later. runtime files use the MIT license. closes: vim/vim#16273 https://github.com/vim/vim/commit/4ce1cb5bf1dc507224792543d8e56e6ab431a2b5 Co-authored-by: Jon Parise <jon@indelible.org>
-rw-r--r--runtime/ftplugin/graphql.vim17
-rw-r--r--runtime/indent/graphql.vim92
-rw-r--r--runtime/syntax/graphql.vim90
3 files changed, 195 insertions, 4 deletions
diff --git a/runtime/ftplugin/graphql.vim b/runtime/ftplugin/graphql.vim
index 56f6e36e20..1717ebf2cc 100644
--- a/runtime/ftplugin/graphql.vim
+++ b/runtime/ftplugin/graphql.vim
@@ -1,13 +1,22 @@
" Vim filetype plugin
" Language: graphql
-" Maintainer: Riley Bruins <ribru17@gmail.com>
-" Last Change: 2024 May 18
+" Maintainer: Jon Parise <jon@indelible.org>
+" Filenames: *.graphql *.graphqls *.gql
+" URL: https://github.com/jparise/vim-graphql
+" License: MIT <https://opensource.org/license/mit>
+" Last Change: 2024 Dec 21
if exists('b:did_ftplugin')
finish
endif
let b:did_ftplugin = 1
-setl comments=:# commentstring=#\ %s
+setlocal comments=:#
+setlocal commentstring=#\ %s
+setlocal formatoptions-=t
+setlocal iskeyword+=$,@-@
+setlocal softtabstop=2
+setlocal shiftwidth=2
+setlocal expandtab
-let b:undo_ftplugin = 'setl com< cms<'
+let b:undo_ftplugin = 'setlocal com< cms< fo< isk< sts< sw< et<'
diff --git a/runtime/indent/graphql.vim b/runtime/indent/graphql.vim
new file mode 100644
index 0000000000..dc0769b9a8
--- /dev/null
+++ b/runtime/indent/graphql.vim
@@ -0,0 +1,92 @@
+" Vim indent file
+" Language: graphql
+" Maintainer: Jon Parise <jon@indelible.org>
+" Filenames: *.graphql *.graphqls *.gql
+" URL: https://github.com/jparise/vim-graphql
+" License: MIT <https://opensource.org/license/mit>
+" Last Change: 2024 Dec 21
+
+" Set our local options if indentation hasn't already been set up.
+" This generally means we've been detected as the primary filetype.
+if !exists('b:did_indent')
+ setlocal autoindent
+ setlocal nocindent
+ setlocal nolisp
+ setlocal nosmartindent
+
+ setlocal indentexpr=GetGraphQLIndent()
+ setlocal indentkeys=0{,0},0),0[,0],0#,!^F,o,O
+
+ let b:did_indent = 1
+endif
+
+" If our indentation function already exists, we have nothing more to do.
+if exists('*GetGraphQLIndent')
+ finish
+endif
+
+let s:cpo_save = &cpoptions
+set cpoptions&vim
+
+" searchpair() skip expression that matches in comments and strings.
+let s:pair_skip_expr =
+ \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "comment\\|string"'
+
+" Check if the character at lnum:col is inside a string.
+function s:InString(lnum, col)
+ return synIDattr(synID(a:lnum, a:col, 1), 'name') ==# 'graphqlString'
+endfunction
+
+function GetGraphQLIndent()
+ " If this is the first non-blank line, we have nothing more to do because
+ " all of our indentation rules are based on matching against earlier lines.
+ let l:prevlnum = prevnonblank(v:lnum - 1)
+ if l:prevlnum == 0
+ return 0
+ endif
+
+ " If the previous line isn't GraphQL, assume we're part of a template
+ " string and indent this new line within it.
+ let l:stack = map(synstack(l:prevlnum, 1), "synIDattr(v:val, 'name')")
+ if get(l:stack, -1) !~# '^graphql'
+ return indent(l:prevlnum) + shiftwidth()
+ endif
+
+ let l:line = getline(v:lnum)
+
+ " If this line contains just a closing bracket, find its matching opening
+ " bracket and indent the closing bracket to match.
+ let l:col = matchend(l:line, '^\s*[]})]')
+ if l:col > 0 && !s:InString(v:lnum, l:col)
+ call cursor(v:lnum, l:col)
+
+ let l:bracket = l:line[l:col - 1]
+ if l:bracket ==# '}'
+ let l:matched = searchpair('{', '', '}', 'bW', s:pair_skip_expr)
+ elseif l:bracket ==# ']'
+ let l:matched = searchpair('\[', '', '\]', 'bW', s:pair_skip_expr)
+ elseif l:bracket ==# ')'
+ let l:matched = searchpair('(', '', ')', 'bW', s:pair_skip_expr)
+ else
+ let l:matched = -1
+ endif
+
+ return l:matched > 0 ? indent(l:matched) : virtcol('.') - 1
+ endif
+
+ " If we're inside of a multiline string, continue with the same indentation.
+ if s:InString(v:lnum, matchend(l:line, '^\s*') + 1)
+ return indent(v:lnum)
+ endif
+
+ " If the previous line ended with an opening bracket, indent this line.
+ if getline(l:prevlnum) =~# '\%(#.*\)\@<![[{(]\s*$'
+ return indent(l:prevlnum) + shiftwidth()
+ endif
+
+ " Default to the existing indentation level.
+ return indent(l:prevlnum)
+endfunction
+
+let &cpoptions = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/syntax/graphql.vim b/runtime/syntax/graphql.vim
new file mode 100644
index 0000000000..01d5ca25ff
--- /dev/null
+++ b/runtime/syntax/graphql.vim
@@ -0,0 +1,90 @@
+" Vim syntax file
+" Language: graphql
+" Maintainer: Jon Parise <jon@indelible.org>
+" Filenames: *.graphql *.graphqls *.gql
+" URL: https://github.com/jparise/vim-graphql
+" License: MIT <https://opensource.org/license/mit>
+" Last Change: 2024 Dec 21
+
+if !exists('main_syntax')
+ if exists('b:current_syntax')
+ finish
+ endif
+ let main_syntax = 'graphql'
+endif
+
+syn case match
+
+syn match graphqlComment "#.*$" contains=@Spell
+
+syn match graphqlOperator "=" display
+syn match graphqlOperator "!" display
+syn match graphqlOperator "|" display
+syn match graphqlOperator "&" display
+syn match graphqlOperator "\M..." display
+
+syn keyword graphqlBoolean true false
+syn keyword graphqlNull null
+syn match graphqlNumber "-\=\<\%(0\|[1-9]\d*\)\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\>" display
+syn region graphqlString start=+"+ skip=+\\\\\|\\"+ end=+"\|$+
+syn region graphqlString start=+"""+ skip=+\\"""+ end=+"""+
+
+syn keyword graphqlKeyword repeatable nextgroup=graphqlKeyword skipwhite
+syn keyword graphqlKeyword on nextgroup=graphqlType,graphqlDirectiveLocation skipwhite
+
+syn keyword graphqlStructure enum scalar type union nextgroup=graphqlType skipwhite
+syn keyword graphqlStructure input interface subscription nextgroup=graphqlType skipwhite
+syn keyword graphqlStructure implements nextgroup=graphqlType skipwhite
+syn keyword graphqlStructure query mutation fragment nextgroup=graphqlName skipwhite
+syn keyword graphqlStructure directive nextgroup=graphqlDirective skipwhite
+syn keyword graphqlStructure extend nextgroup=graphqlStructure skipwhite
+syn keyword graphqlStructure schema nextgroup=graphqlFold skipwhite
+
+syn match graphqlDirective "\<@\h\w*\>" display
+syn match graphqlVariable "\<\$\h\w*\>" display
+syn match graphqlName "\<\h\w*\>" display
+syn match graphqlType "\<_*\u\w*\>" display
+
+" https://spec.graphql.org/October2021/#ExecutableDirectiveLocation
+syn keyword graphqlDirectiveLocation QUERY MUTATION SUBSCRIPTION FIELD
+syn keyword graphqlDirectiveLocation FRAGMENT_DEFINITION FRAGMENT_SPREAD
+syn keyword graphqlDirectiveLocation INLINE_FRAGMENT VARIABLE_DEFINITION
+" https://spec.graphql.org/October2021/#TypeSystemDirectiveLocation
+syn keyword graphqlDirectiveLocation SCHEMA SCALAR OBJECT FIELD_DEFINITION
+syn keyword graphqlDirectiveLocation ARGUMENT_DEFINITION INTERFACE UNION
+syn keyword graphqlDirectiveLocation ENUM ENUM_VALUE INPUT_OBJECT
+syn keyword graphqlDirectiveLocation INPUT_FIELD_DEFINITION
+
+syn keyword graphqlMetaFields __schema __type __typename
+
+syn region graphqlFold matchgroup=graphqlBraces start="{" end="}" transparent fold contains=ALLBUT,graphqlStructure
+syn region graphqlList matchgroup=graphqlBraces start="\[" end="]" transparent contains=ALLBUT,graphqlDirective,graphqlStructure
+
+if main_syntax ==# 'graphql'
+ syn sync minlines=500
+endif
+
+hi def link graphqlComment Comment
+hi def link graphqlOperator Operator
+
+hi def link graphqlBraces Delimiter
+
+hi def link graphqlBoolean Boolean
+hi def link graphqlNull Keyword
+hi def link graphqlNumber Number
+hi def link graphqlString String
+
+hi def link graphqlDirective PreProc
+hi def link graphqlDirectiveLocation Special
+hi def link graphqlName Identifier
+hi def link graphqlMetaFields Special
+hi def link graphqlKeyword Keyword
+hi def link graphqlStructure Structure
+hi def link graphqlType Type
+hi def link graphqlVariable Identifier
+
+let b:current_syntax = 'graphql'
+
+if main_syntax ==# 'graphql'
+ unlet main_syntax
+endif