Add gdscript, closes #483

This commit is contained in:
Adam Stankiewicz
2020-04-25 21:06:45 +02:00
parent 68b2748af1
commit b2ee28374b
8 changed files with 497 additions and 1 deletions

View File

@@ -10,7 +10,7 @@ A collection of language packs for Vim.
> One to rule them all, one to find them, one to bring them all and in the darkness bind them.
- It **won't affect your startup time**, as scripts are loaded only on demand\*.
- It **installs and updates 120+ times faster** than the <!--Package Count-->146<!--/Package Count--> packages it consists of.
- It **installs and updates 120+ times faster** than the <!--Package Count-->147<!--/Package Count--> packages it consists of.
- Solid syntax and indentation support (other features skipped). Only the best language packs.
- All unnecessary files are ignored (like enormous documentation from php support).
- No support for esoteric languages, only most popular ones (modern too, like `slim`).
@@ -80,6 +80,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [fish](https://github.com/georgewitteman/vim-fish) (syntax, indent, compiler, autoload, ftplugin)
- [flatbuffers](https://github.com/dcharbon/vim-flatbuffers) (syntax)
- [fsharp](https://github.com/fsharp/vim-fsharp) (syntax, indent)
- [gdscript](https://github.com/calviken/vim-gdscript3) (syntax, indent, ftplugin)
- [git](https://github.com/tpope/vim-git) (syntax, indent, ftplugin)
- [glsl](https://github.com/tikhomirov/vim-glsl) (syntax, indent)
- [gmpl](https://github.com/maelvalais/gmpl.vim) (syntax)

1
build
View File

@@ -198,6 +198,7 @@ PACKS="
fish:georgewitteman/vim-fish
flatbuffers:dcharbon/vim-flatbuffers
fsharp:fsharp/vim-fsharp:_BASIC
gdscript:calviken/vim-gdscript3
git:tpope/vim-git
glsl:tikhomirov/vim-glsl:_NOAFTER
gmpl:maelvalais/gmpl.vim

View File

@@ -461,6 +461,20 @@ autocmd BufNewFile,BufRead *.fs,*.fsi,*.fsx set filetype=fsharp
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
augroup filetypedetect
" gdscript, from gdscript3.vim in calviken/vim-gdscript3
autocmd BufRead,BufNewFile *.gd set filetype=gdscript3
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
augroup filetypedetect
" gdscript, from gsl.vim in calviken/vim-gdscript3
autocmd BufRead,BufNewFile *.shader set filetype=gsl
augroup end
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'glsl') == -1
augroup filetypedetect
" glsl, from glsl.vim in tikhomirov/vim-glsl:_NOAFTER

107
ftplugin/gdscript3.vim Normal file
View File

@@ -0,0 +1,107 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
setlocal commentstring=#\ %s
if exists("g:gdscript3_loaded")
finish
endif
let g:gdscript3_loaded=1
if !has("python3") && !has("python")
finish
endif
if has("python3")
let s:pyfile_cmd = "py3file"
let s:py_cmd = "py3"
else
let s:pyfile_cmd = "pyfile"
let s:py_cmd = "py"
endif
execute s:pyfile_cmd . " " . expand('<sfile>:p:h') . "/../python/init.py"
fun! GDScriptComplete(findstart, base)
if a:findstart == 1
let line = getline('.')
let start = col('.') - 1
" Treat '-' as part of the word when completing in a string.
if synIDattr(synID(line('.'), col('.')-1, 1), 'name') ==# "gdString"
let pattern = '[-a-zA-Z0-9_]'
else
let pattern = '[a-zA-Z0-9_]'
endif
while start > 0 && line[start - 1] =~ pattern
let start -= 1
endwhile
return start
else
execute s:py_cmd . " gdscript_complete()"
if exists("gdscript_completions")
return gdscript_completions
else
return []
endif
endif
endfun
set omnifunc=GDScriptComplete
" Configure for common completion frameworks.
" Deoplete
if &rtp =~ 'deoplete.nvim'
call deoplete#custom#option('sources', {
\ 'gdscript3': ['omni'],
\ })
call deoplete#custom#var('omni', 'input_patterns', {
\ 'gdscript3': [
\ '\.|\w+',
\ '\bextends\s+',
\ '\bexport\(',
\ '\bfunc\s+',
\ '"res://[^"]*'
\ ]
\ })
endif
" SuperTab
let g:SuperTabDefaultCompletionType = "<c-x><c-o>"
" YouCompleteMe
if !exists('g:ycm_semantic_triggers')
let g:ycm_semantic_triggers = {}
endif
let g:ycm_semantic_triggers.gdscript3 = [
\'re!\w+',
\'.',
\'re!\bextends\s+',
\'re!\bexport\(',
\'re!\bfunc\s+',
\'re!"res://[^"]*'
\]
" Configure echodoc
if &rtp =~ 'echodoc'
let s:echodoc_dict = { "name": "gdscript3", "rank": 9 }
fun! s:echodoc_dict.search(text)
execute s:py_cmd . " echodoc_search()"
if exists("echodoc_search_result")
return echodoc_search_result
else
return []
endif
endfun
call echodoc#register('gdscript3', s:echodoc_dict)
" Reset echodoc cache when exiting insert mode.
" This fixes an issue where the function signature wouldn't re-appear
" after exiting and re-entering insert mode.
au InsertLeave * let b:prev_echodoc = []
endif
" Configure Syntastic checker
let g:syntastic_gdscript3_checkers = ['godot_server']
endif

5
ftplugin/gsl.vim Normal file
View File

@@ -0,0 +1,5 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
setlocal commentstring=//\ %s
endif

204
indent/gdscript3.vim Normal file
View File

@@ -0,0 +1,204 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
" Vim indent file
" Language: Python
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Original Author: David Bustos <bustos@caltech.edu>
" Last Change: 2013 Jul 9
" Modified for GDScript
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
" Some preliminary settings
setlocal nolisp " Make sure lisp indenting doesn't supersede us
setlocal autoindent " indentexpr isn't much help otherwise
setlocal indentexpr=GetPythonIndent(v:lnum)
setlocal indentkeys+=<:>,=elif
" Only define the function once.
if exists("*GetPythonIndent")
finish
endif
let s:keepcpo= &cpo
set cpo&vim
" Come here when loading the script the first time.
let s:maxoff = 50 " maximum number of lines to look backwards for ()
function GetPythonIndent(lnum)
" If this line is explicitly joined: If the previous line was also joined,
" line it up with that one, otherwise add two 'shiftwidth'
if getline(a:lnum - 1) =~ '\\$'
if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$'
return indent(a:lnum - 1)
endif
return indent(a:lnum - 1) + (exists("g:pyindent_continue") ? eval(g:pyindent_continue) : (shiftwidth() * 2))
endif
" If the start of the line is in a string don't change the indent.
if has('syntax_items')
\ && synIDattr(synID(a:lnum, 1, 1), "name") =~ "String$"
return -1
endif
" Search backwards for the previous non-empty line.
let plnum = prevnonblank(v:lnum - 1)
if plnum == 0
" This is the first non-empty line, use zero indent.
return 0
endif
" If the previous line is inside parenthesis, use the indent of the starting
" line.
" Trick: use the non-existing "dummy" variable to break out of the loop when
" going too far back.
call cursor(plnum, 1)
let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW',
\ "line('.') < " . (plnum - s:maxoff) . " ? dummy :"
\ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
\ . " =~ '\\(Comment\\|Todo\\|String\\)$'")
if parlnum > 0
let plindent = indent(parlnum)
let plnumstart = parlnum
else
let plindent = indent(plnum)
let plnumstart = plnum
endif
" When inside parenthesis: If at the first line below the parenthesis add
" two 'shiftwidth', otherwise same as previous line.
" i = (a
" + b
" + c)
call cursor(a:lnum, 1)
let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
\ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
\ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
\ . " =~ '\\(Comment\\|Todo\\|String\\)$'")
if p > 0
if p == plnum
" When the start is inside parenthesis, only indent one 'shiftwidth'.
let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
\ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
\ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
\ . " =~ '\\(Comment\\|Todo\\|String\\)$'")
if pp > 0
return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth())
endif
return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (shiftwidth() * 2))
endif
if plnumstart == p
return indent(plnum)
endif
return plindent
endif
" Get the line and remove a trailing comment.
" Use syntax highlighting attributes when possible.
let pline = getline(plnum)
let pline_len = strlen(pline)
if has('syntax_items')
" If the last character in the line is a comment, do a binary search for
" the start of the comment. synID() is slow, a linear search would take
" too long on a long line.
if synIDattr(synID(plnum, pline_len, 1), "name") =~ "\\(Comment\\|Todo\\)$"
let min = 1
let max = pline_len
while min < max
let col = (min + max) / 2
if synIDattr(synID(plnum, col, 1), "name") =~ "\\(Comment\\|Todo\\)$"
let max = col
else
let min = col + 1
endif
endwhile
let pline = strpart(pline, 0, min - 1)
endif
else
let col = 0
while col < pline_len
if pline[col] == '#'
let pline = strpart(pline, 0, col)
break
endif
let col = col + 1
endwhile
endif
" If the previous line ended with a colon, indent this line
if pline =~ ':\s*$'
return plindent + shiftwidth()
endif
" If the previous line was a stop-execution statement...
if getline(plnum) =~ '^\s*\(break\|continue\|return\|pass\)\>'
" See if the user has already dedented
if indent(a:lnum) > indent(plnum) - shiftwidth()
" If not, recommend one dedent
return indent(plnum) - shiftwidth()
endif
" Otherwise, trust the user
return -1
endif
" If the current line begins with a keyword that lines up with "try"
" if getline(a:lnum) =~ '^\s*\(except\|finally\)\>'
" let lnum = a:lnum - 1
" while lnum >= 1
" if getline(lnum) =~ '^\s*\(try\|except\)\>'
" let ind = indent(lnum)
" if ind >= indent(a:lnum)
" return -1 " indent is already less than this
" endif
" return ind " line up with previous try or except
" endif
" let lnum = lnum - 1
" endwhile
" return -1 " no matching "try"!
" endif
" If the current line begins with a header keyword, dedent
if getline(a:lnum) =~ '^\s*\(elif\|else\)\>'
" Unless the previous line was a one-liner
if getline(plnumstart) =~ '^\s*\(for\|if\)\>'
return plindent
endif
" Or the user has already dedented
if indent(a:lnum) <= plindent - shiftwidth()
return -1
endif
return plindent - shiftwidth()
endif
" When after a () construct we probably want to go back to the start line.
" a = (b
" + c)
" here
if parlnum > 0
return plindent
endif
return -1
endfunction
let &cpo = s:keepcpo
unlet s:keepcpo
" vim:sw=2
endif

101
syntax/gdscript3.vim Normal file
View File

@@ -0,0 +1,101 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
" Syntax file for GDScript
if exists("b:current_syntax")
finish
endif
let b:current_syntax = "gdscript3"
let s:save_cpo = &cpo
set cpo&vim
syn keyword gdConditional if elif else match
syn keyword gdRepeat for while
syn keyword gdOperator and or not is in
syn match gdOperator "\V&&\|||\|!\|&\|^\||\|~\|*\|/\|%\|+\|-\|=\|<\|>"
syn match gdDelimiter "\V(\|)\|[\|]\|{\|}"
syn keyword gdStatement break continue pass return
syn keyword gdKeyword extends tool signal self
\ const enum var onready export setget
syn match gdKeyword "\v^\s*((static\s*)=func|class)"
\ nextgroup=gdFunction skipwhite
syn keyword gdBoolean true false
syn match gdMember "\v<(\.)@<=[a-z_]+\w*>"
syn match gdFunction "\v<\w*>(\()@="
syn match gdSignal "\v(<signal>\s+)@<=<\w+>"
syn match gdSetGet "\v(<setget>\s+)@<=<\w+>"
syn match gdSetGet "\v(<setget>\s+\w*\s*,\s*)@<=<\w+>"
syn keyword gdNull null
syn keyword gdClass int float bool
syn match gdClass "\v<\u\w+>"
syn match gdConstant "\v<[A-Z_]+[A-Z0-9_]*>"
syn keyword gdClass AABB IP JSON OS RID
syn match gdNode "\v\$\a+\w*"
syn region gdString start='\v\"' end='\v\"'
syn region gdString start='\v\'' end='\v\''
syn match gdEscapeError "\v\\." containedin=gdString
syn match gdEscapeError "\v\\u.{,3}" containedin=gdString
syn match gdEscape "\v\\[abfnrtv\\'"]" containedin=gdString
syn match gdEscape "\v\\u[0-9]{4}" containedin=gdString
syn match gdFormat "\v\%\%" containedin=gdString
syn match gdFormat "\v\%[+-]=(\d*|\*)=\.=(\d*|\*)=[scdoxXf]" containedin=gdString
syn match gdNumber "\v<\d+(\.)@!>"
syn match gdNumber "\v<0x\x+(\.)@!>"
syn match gdFloat "\v<\d*\.\d+(\.)@!>"
syn match gdFloat "\v<\d*\.=\d+(e-=\d+)@="
syn match gdExponent "\v(\d*\.=\d+)@<=e-=\d+>"
syn match gdComment "\v#.*$"
syn keyword gdTodo TODO FIXME XXX NOTE BUG HACK OPTIMIZE containedin=gdComment
syn region gdFunctionFold
\ start="\v^\z(\s*)%(%(static\s+)=func|class)>"
\ end="\v\ze%(\s*\n)+%(\z1\s)@!."
\ fold transparent
syn region gdFold
\ matchgroup=gdComment
\ start='#.*{{{.*$'
\ end='#.*}}}.*$'
\ fold transparent
hi def link gdConditional Conditional
hi def link gdRepeat Repeat
hi def link gdOperator Operator
hi def link gdDelimiter Delimiter
hi def link gdStatement Statement
hi def link gdKeyword Keyword
hi def link gdBoolean Boolean
hi def link gdMember Identifier
hi def link gdFunction Function
hi def link gdSignal Function
hi def link gdSetGet Function
hi def link gdNull Constant
hi def link gdClass Type
hi def link gdConstant Constant
hi def link gdNode Identifier
hi def link gdString String
hi def link gdEscape Special
hi def link gdFormat Special
hi def link gdNumber Number
hi def link gdFloat Float
hi def link gdExponent Special
hi def link gdEscapeError Error
hi def link gdComment Comment
hi def link gdTodo Todo
let &cpo = s:save_cpo
unlet s:save_cpo
endif

63
syntax/gsl.vim Normal file
View File

@@ -0,0 +1,63 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gdscript') == -1
" Syntax file for Godot Shading Language
if exists("b:current_syntax")
finish
endif
let b:current_syntax = "gsl"
let s:save_cpo = &cpo
set cpo&vim
syn keyword gslConditional if else
syn keyword gslRepeat for while
syn match gslOperator "\V&&\|||\|!\|&\|^\||\|~\|*\|/\|%\|+\|-\|=\|<\|>\|;"
syn match gslDelimiter "\V(\|)\|[\|]\|{\|}"
syn keyword gslStatement return discard
syn keyword gslBoolean true false
syn keyword gslKeyword shader_type render_mode varying flat noperspective smooth
\ uniform lowp mediump highp in out inout
syn keyword gslType void bool bvec2 bvec3 bvec4 int ivec2 ivec3 ivec4
\ uint uvec2 uvec3 uvec4 float vec2 vec3 vec4
\ mat2 mat3 mat4 sampler2D isampler2D usampler2D samplerCube
syn match gslMember "\v<(\.)@<=[a-z_]+\w*>"
syn match gslConstant "\v<[A-Z_]+[A-Z0-9_]*>"
syn match gslFunction "\v<\w*>(\()@="
syn match gslNumber "\v<\d+(\.)@!>"
syn match gslFloat "\v<\d*\.\d+(\.)@!>"
syn match gslFloat "\v<\d*\.=\d+(e-=\d+)@="
syn match gslExponent "\v(\d*\.=\d+)@<=e-=\d+>"
syn match gslComment "\v//.*$"
syn region gslComment start="/\*" end="\*/"
syn keyword gslTodo TODO FIXME XXX NOTE BUG HACK OPTIMIZE containedin=gslComment
hi def link gslConditional Conditional
hi def link gslRepeat Repeat
hi def link gslOperator Operator
hi def link gslDelimiter Delimiter
hi def link gslStatement Statement
hi def link gslBoolean Boolean
hi def link gslKeyword Keyword
hi def link gslMember Identifier
hi def link gslConstant Constant
hi def link gslFunction Function
hi def link gslType Type
hi def link gslNumber Number
hi def link gslFloat Float
hi def link gslExponent Special
hi def link gslComment Comment
hi def link gslTodo Todo
let &cpo = s:save_cpo
unlet s:save_cpo
endif