summaryrefslogtreecommitdiffstats
path: root/runtime/indent/nginx.vim
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-12-31 15:30:45 +0000
committerBram Moolenaar <Bram@vim.org>2022-12-31 15:30:45 +0000
commitf1dcd14fc5d4370476cd82895a4479ca2d252e54 (patch)
treec5d20989d5b5d69af7f0935c7e6f929126c0e5b8 /runtime/indent/nginx.vim
parentdb4d88c2adfe8f8122341ac9d6cae27ef78451c8 (diff)
Update runtime files
Diffstat (limited to 'runtime/indent/nginx.vim')
-rw-r--r--runtime/indent/nginx.vim77
1 files changed, 68 insertions, 9 deletions
diff --git a/runtime/indent/nginx.vim b/runtime/indent/nginx.vim
index 8cef7662e0..65506099f4 100644
--- a/runtime/indent/nginx.vim
+++ b/runtime/indent/nginx.vim
@@ -1,19 +1,78 @@
" Vim indent file
" Language: nginx.conf
" Maintainer: Chris Aumann <me@chr4.org>
-" Last Change: 2022 Apr 06
+" Last Change: 2022 Dec 01
-if exists("b:did_indent")
- finish
+" Only load this indent file when no other was loaded.
+if exists('b:did_indent')
+ finish
endif
let b:did_indent = 1
-setlocal indentexpr=
+setlocal indentexpr=GetNginxIndent()
-" cindent actually works for nginx' simple file structure
-setlocal cindent
+setlocal indentkeys=0{,0},0#,!^F,o,O
-" Just make sure that the comments are not reset as defs would be.
-setlocal cinkeys-=0#
+let b:undo_indent = 'setl inde< indk<'
-let b:undo_indent = "setl inde< cin< cink<"
+" Only define the function once.
+if exists('*GetNginxIndent')
+ finish
+endif
+
+function GetNginxIndent() abort
+ let plnum = s:PrevNotAsBlank(v:lnum - 1)
+
+ " Hit the start of the file, use zero indent.
+ if plnum == 0
+ return 0
+ endif
+
+ let ind = indent(plnum)
+
+ " Add a 'shiftwidth' after '{'
+ if s:AsEndWith(getline(plnum), '{')
+ let ind = ind + shiftwidth()
+ end
+
+ " Subtract a 'shiftwidth' on '}'
+ " This is the part that requires 'indentkeys'.
+ if getline(v:lnum) =~ '^\s*}'
+ let ind = ind - shiftwidth()
+ endif
+
+ let pplnum = s:PrevNotAsBlank(plnum - 1)
+
+ if s:IsLineContinuation(plnum)
+ if !s:IsLineContinuation(pplnum)
+ let ind = ind + shiftwidth()
+ end
+ else
+ if s:IsLineContinuation(pplnum)
+ let ind = ind - shiftwidth()
+ end
+ endif
+
+ return ind
+endfunction
+
+" Find the first line at or above {lnum} that is non-blank and not a comment.
+function s:PrevNotAsBlank(lnum) abort
+ let lnum = prevnonblank(a:lnum)
+ while lnum > 0
+ if getline(lnum) !~ '^\s*#'
+ break
+ endif
+ let lnum = prevnonblank(lnum - 1)
+ endwhile
+ return lnum
+endfunction
+
+" Check whether {line} ends with {pat}, ignoring trailing comments.
+function s:AsEndWith(line, pat) abort
+ return a:line =~ a:pat . '\m\s*\%(#.*\)\?$'
+endfunction
+
+function s:IsLineContinuation(lnum) abort
+ return a:lnum > 0 && !s:AsEndWith(getline(a:lnum), '[;{}]')
+endfunction