gdscript.vim (4550B)
1 " Vim indent file 2 " Language: gdscript (Godot game engine) 3 " Maintainer: Maxim Kim <habamax@gmail.com> 4 " Based on python indent file. 5 " 6 " This file has been manually translated from Vim9 script. 7 8 if exists("b:did_indent") 9 finish 10 endif 11 let b:did_indent = 1 12 13 let s:save_cpo = &cpo 14 set cpo&vim 15 16 let s:undo_opts = "setl indentexpr< indentkeys< lisp< autoindent<" 17 18 if exists('b:undo_indent') 19 let b:undo_indent ..= "|" .. s:undo_opts 20 else 21 let b:undo_indent = s:undo_opts 22 endif 23 24 setlocal nolisp 25 setlocal autoindent 26 setlocal indentexpr=s:GDScriptIndent() 27 setlocal indentkeys+=<:>,=elif,=except 28 29 30 function s:GDScriptIndent() abort 31 " If this line is explicitly joined: If the previous line was also joined, 32 " line it up with that one, otherwise add two 'shiftwidth' 33 if getline(v:lnum - 1) =~# '\\$' 34 if v:lnum > 1 && getline(v:lnum - 2) =~# '\\$' 35 return indent(v:lnum - 1) 36 endif 37 return indent(v:lnum - 1) + (shiftwidth() * 2) 38 endif 39 40 " If the start of the line is in a string don't change the indent. 41 if has('syntax_items') && synIDattr(synID(v:lnum, 1, 1), "name") =~# "String$" 42 return -1 43 endif 44 45 " Search backwards for the previous non-empty line. 46 let plnum = prevnonblank(v:lnum - 1) 47 48 if plnum == 0 49 " This is the first non-empty line, use zero indent. 50 return 0 51 endif 52 53 let plindent = indent(plnum) 54 let plnumstart = plnum 55 56 " Get the line and remove a trailing comment. 57 " Use syntax highlighting attributes when possible. 58 let pline = getline(plnum) 59 let pline_len = strlen(pline) 60 if has('syntax_items') 61 " If the last character in the line is a comment, do a binary search for 62 " the start of the comment. synID() is slow, a linear search would take 63 " too long on a long line. 64 if synIDattr(synID(plnum, pline_len, 1), "name") =~# "\\(Comment\\|Todo\\)$" 65 let min = 1 66 let max = pline_len 67 while min < max 68 let col = (min + max) / 2 69 if synIDattr(synID(plnum, col, 1), "name") =~# "\\(Comment\\|Todo\\)$" 70 let max = col 71 else 72 let min = col + 1 73 endif 74 endwhile 75 let pline = strpart(pline, 0, min - 1) 76 endif 77 else 78 let col = 0 79 while col < pline_len 80 if pline[col] ==# '#' 81 let pline = strpart(pline, 0, col) 82 break 83 endif 84 let col = col + 1 85 endwhile 86 endif 87 88 89 " When "inside" parenthesis: If at the first line below the parenthesis add 90 " one 'shiftwidth' ("inside" is simplified and not really checked) 91 " my_var = ( 92 " a 93 " + b 94 " + c 95 " ) 96 if pline =~# '[({\[]\s*$' 97 return indent(plnum) + shiftwidth() 98 endif 99 100 101 " If the previous line ended with a colon, indent this line 102 if pline =~# ':\s*$' 103 return plindent + shiftwidth() 104 endif 105 106 " If the previous line was a stop-execution statement... 107 if getline(plnum) =~# '^\s*\(break\|continue\|raise\|return\|pass\)\>' 108 " See if the user has already dedented 109 if indent(v:lnum) > indent(plnum) - shiftwidth() 110 " If not, recommend one dedent 111 return indent(plnum) - shiftwidth() 112 endif 113 " Otherwise, trust the user 114 return -1 115 endif 116 117 " If the current line begins with a keyword that lines up with "try" 118 if getline(v:lnum) =~# '^\s*\(except\|finally\)\>' 119 let lnum = v:lnum - 1 120 while lnum >= 1 121 if getline(lnum) =~# '^\s*\(try\|except\)\>' 122 let ind = indent(lnum) 123 if ind >= indent(v:lnum) 124 return -1 " indent is already less than this 125 endif 126 return ind " line up with previous try or except 127 endif 128 let lnum = lnum - 1 129 endwhile 130 return -1 " no matching "try"! 131 endif 132 133 134 " If the current line begins with a header keyword, dedent 135 if getline(v:lnum) =~# '^\s*\(elif\|else\)\>' 136 137 " Unless the previous line was a one-liner 138 if getline(plnumstart) =~# '^\s*\(for\|if\|try\)\>' 139 return plindent 140 endif 141 142 " Or the user has already dedented 143 if indent(v:lnum) <= plindent - shiftwidth() 144 return -1 145 endif 146 147 return plindent - shiftwidth() 148 endif 149 150 return -1 151 endfunction 152 153 let &cpo = s:save_cpo 154 unlet s:save_cpo