Last active
April 4, 2022 14:38
-
-
Save bonsaiviking/8845871 to your computer and use it in GitHub Desktop.
A Vim indent file for the Lua scripting language. Install as ~/.vim/indent/lua.vim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Vim indent file | |
" Language: Lua | |
" Maintainer: Daniel Miller <[email protected]> | |
" Original Author: Daniel Miller <[email protected]> | |
" Last Change: 2014 Feb 6 | |
" 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=GetLuaIndent() | |
setlocal indentkeys+==end,=until,=elseif,=else | |
" Only define the function once. | |
if exists("*GetLuaIndent") | |
finish | |
endif | |
" Come here when loading the script the first time. | |
function IsValidMatch() | |
"echom synIDattr(synID(line('.'), col('.'), 1), 'name') . " match " | |
" \ . getline(".")[col(".")-1] . " in col " . col(".") | |
return synIDattr(synID(line('.'), col('.'), 1), 'name') =~ '\%(Comment\|String2\?\)$' | |
endfunction | |
function GetLuaIndent() | |
let openmatch = '\%(\<\%(function\|if\|repeat\|do\)\>\|(\|{\|\[\)' | |
let middlematch = '\<\%(else\|elseif\)\>' | |
let closematch = '\%(\<\%(end\|until\)\>\|)\|}\|\]\)' | |
let save_cursor = getpos(".") | |
" If the start of the line is in a [[string]] don't change the indent. | |
if has('syntax_items') | |
\ && synIDattr(synID(v:lnum, 1, 1), "name") =~ 'String2$' | |
"echom "String, no indent" | |
return -1 | |
endif | |
" Search backwards for the previous non-empty line. | |
let plnum = prevnonblank(v:lnum - 1) | |
" [[multiline strings]] shouldn't affect indentation | |
while synIDattr(synID(plnum, 1, 1), 'name') =~ 'String2$' | |
let plnum = prevnonblank(plnum - 1) | |
endwhile | |
if plnum == 0 | |
" This is the first non-empty line, use zero indent. | |
return 0 | |
endif | |
let i = 0 | |
"check open keywords on line above | |
call cursor(v:lnum, 1) | |
let parnum = searchpair(openmatch, | |
\ middlematch, closematch, 'mWrb', | |
\ "IsValidMatch()", plnum) | |
if parnum > 0 | |
"echom parnum . "open matches above" | |
let i += parnum | |
endif | |
"check closed keywords on current line | |
call cursor(plnum, col([plnum,'$'])) | |
let parnum = searchpair(openmatch, | |
\ middlematch, closematch, 'mWr', | |
\ "IsValidMatch()", v:lnum) | |
if parnum > 0 | |
"echom parnum . "closed matches here" | |
let i -= parnum | |
endif | |
"Special case for parentheses (indent the closing paren) | |
"If the previous line closed a paren, dedent | |
call cursor(plnum - 1, col([plnum - 1, '$'])) | |
let parnum = searchpair('(', '', ')', 'mWr', | |
\ "IsValidMatch()", plnum) | |
if parnum > 0 | |
"echom parnum . "closed parens above" | |
let i -= 1 | |
endif | |
"If this line closed a paren, indent | |
call cursor(plnum, col([plnum, '$'])) | |
let parnum = searchpair('(', '', ')', 'mWr', | |
\ "IsValidMatch()", v:lnum) | |
if parnum > 0 | |
"echom parnum . "closed parens here" | |
let i += 1 | |
endif | |
"restore cursor | |
call setpos(".", save_cursor) | |
"return the calculated indent | |
return indent(plnum) + (&sw * i) | |
endfunction | |
" vim:sw=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment