mirror of
				https://github.com/vim/vim.git
				synced 2025-10-28 09:27:14 -04:00 
			
		
		
		
	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: #16273 Signed-off-by: Jon Parise <jon@indelible.org> Signed-off-by: Christian Brabandt <cb@256bit.org>
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
| " 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
 |