diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2020-10-06 18:54:19 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2020-10-06 18:54:19 +0200 |
commit | bc9757916ed09763d96283ee62dbed58bd713a11 (patch) | |
tree | 07fbb58e9a4f4cbf5206d89f61e4d570e64d2c1a /indent | |
parent | c6fa4d2bf5eb5301f4d3f123031cf34839a5508d (diff) | |
download | vim-polyglot-bc9757916ed09763d96283ee62dbed58bd713a11.tar.gz vim-polyglot-bc9757916ed09763d96283ee62dbed58bd713a11.zip |
Add all vim filetypes
Diffstat (limited to 'indent')
69 files changed, 6803 insertions, 159 deletions
diff --git a/indent/bib.vim b/indent/bib.vim new file mode 100644 index 00000000..677b19df --- /dev/null +++ b/indent/bib.vim @@ -0,0 +1,19 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'bib') == -1 + +" Vim indent file +" Language: BibTeX +" Maintainer: Dorai Sitaram <ds26@gte.com> +" URL: http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html +" Last Change: 2005 Mar 28 + +" Only do this when not done yet for this buffer +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal cindent + +let b:undo_indent = "setl cin<" + +endif diff --git a/indent/bst.vim b/indent/bst.vim new file mode 100644 index 00000000..6d41acf8 --- /dev/null +++ b/indent/bst.vim @@ -0,0 +1,79 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'bst') == -1 + +" Vim indent file +" Language: bst +" Author: Tim Pope <vimNOSPAM@tpope.info> +" $Id: bst.vim,v 1.1 2007/05/05 18:11:12 vimboss Exp $ + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal expandtab +setlocal indentexpr=GetBstIndent(v:lnum) +"setlocal smartindent +setlocal cinkeys& +setlocal cinkeys-=0# +setlocal indentkeys& +"setlocal indentkeys+=0% + +" Only define the function once. +if exists("*GetBstIndent") + finish +endif + +function! s:prevgood(lnum) + " Find a non-blank line above the current line. + " Skip over comments. + let lnum = a:lnum + while lnum > 0 + let lnum = prevnonblank(lnum - 1) + if getline(lnum) !~ '^\s*%.*$' + break + endif + endwhile + return lnum +endfunction + +function! s:strip(lnum) + let line = getline(a:lnum) + let line = substitute(line,'"[^"]*"','""','g') + let line = substitute(line,'%.*','','') + let line = substitute(line,'^\s\+','','') + return line +endfunction + +function! s:count(string,char) + let str = substitute(a:string,'[^'.a:char.']','','g') + return strlen(str) +endfunction + +function! GetBstIndent(lnum) abort + if a:lnum == 1 + return 0 + endif + let lnum = s:prevgood(a:lnum) + if lnum <= 0 + return indent(a:lnum - 1) + endif + let line = s:strip(lnum) + let cline = s:strip(a:lnum) + if cline =~ '^}' && exists("b:current_syntax") + call cursor(a:lnum,indent(a:lnum)) + if searchpair('{','','}','bW',"synIDattr(synID(line('.'),col('.'),1),'name') =~? 'comment\\|string'") + if col('.')+1 == col('$') + return indent('.') + else + return virtcol('.')-1 + endif + endif + endif + let fakeline = substitute(line,'^}','','').matchstr(cline,'^}') + let ind = indent(lnum) + let ind = ind + shiftwidth() * s:count(line,'{') + let ind = ind - shiftwidth() * s:count(fakeline,'}') + return ind +endfunction + +endif diff --git a/indent/cdl.vim b/indent/cdl.vim new file mode 100644 index 00000000..844ae717 --- /dev/null +++ b/indent/cdl.vim @@ -0,0 +1,133 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'cdl') == -1 + +" Description: Comshare Dimension Definition Language (CDL) +" Author: Raul Segura Acevedo <raulseguraaceved@netscape.net> +" Last Change: Fri Nov 30 13:35:48 2001 CST + +if exists("b:did_indent") + "finish +endif +let b:did_indent = 1 + +setlocal indentexpr=CdlGetIndent(v:lnum) +setlocal indentkeys& +setlocal indentkeys+==~else,=~endif,=~then,;,),= + +" Only define the function once. +if exists("*CdlGetIndent") + "finish +endif + +" find out if an "...=..." expresion is an assignment (or a conditional) +" it scans 'line' first, and then the previos lines +fun! CdlAsignment(lnum, line) + let f = -1 + let lnum = a:lnum + let line = a:line + while lnum > 0 && f == -1 + " line without members [a] of [b]:[c]... + let inicio = 0 + while 1 + " keywords that help to decide + let inicio = matchend(line, '\c\<\(expr\|\a*if\|and\|or\|not\|else\|then\|memberis\|\k\+of\)\>\|[<>;]', inicio) + if inicio < 0 + break + endif + " it's formula if there's a ';', 'elsE', 'theN', 'enDif' or 'expr' + " conditional if there's a '<', '>', 'elseif', 'if', 'and', 'or', 'not', + " 'memberis', 'childrenof' and other \k\+of funcions + let f = line[inicio-1] =~? '[en;]' || strpart(line, inicio-4, 4) =~? 'ndif\|expr' + endw + let lnum = prevnonblank(lnum-1) + let line = substitute(getline(lnum), '\c\(\[[^]]*]\(\s*of\s*\|:\)*\)\+', ' ', 'g') + endw + " if we hit the start of the file then f = -1, return 1 (formula) + return f != 0 +endf + +fun! CdlGetIndent(lnum) + let thisline = getline(a:lnum) + if match(thisline, '^\s*\(\k\+\|\[[^]]*]\)\s*\(,\|;\s*$\)') >= 0 + " it's an attributes line + return shiftwidth() + elseif match(thisline, '^\c\s*\([{}]\|\/[*/]\|dimension\|schedule\|group\|hierarchy\|class\)') >= 0 + " it's a header or '{' or '}' or a comment + return 0 + end + + let lnum = prevnonblank(a:lnum-1) + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + " PREVIOUS LINE + let ind = indent(lnum) + let line = getline(lnum) + let f = -1 " wether a '=' is a conditional or a asignment, -1 means we don't know yet + " one 'closing' element at the beginning of the line has already reduced the + " indent, but 'else', 'elseif' & 'then' increment it for the next line + " '=' at the beginning has already de right indent (increased for asignments) + let inicio = matchend(line, '^\c\s*\(else\a*\|then\|endif\|/[*/]\|[);={]\)') + if inicio > 0 + let c = line[inicio-1] + " ')' and '=' don't change indent and are useless to set 'f' + if c == '{' + return shiftwidth() + elseif c != ')' && c != '=' + let f = 1 " all but 'elseif' are followed by a formula + if c ==? 'n' || c ==? 'e' " 'then', 'else' + let ind = ind + shiftwidth() + elseif strpart(line, inicio-6, 6) ==? 'elseif' " elseif, set f to conditional + let ind = ind + shiftwidth() + let f = 0 + end + end + end + + " remove members [a] of [b]:[c]... (inicio remainds valid) + let line = substitute(line, '\c\(\[[^]]*]\(\s*of\s*\|:\)*\)\+', ' ', 'g') + while 1 + " search for the next interesting element + let inicio=matchend(line, '\c\<if\|endif\|[()=;]', inicio) + if inicio < 0 + break + end + + let c = line[inicio-1] + " 'expr(...)' containing the formula + if strpart(line, inicio-5, 5) ==? 'expr(' + let ind = 0 + let f = 1 + elseif c == ')' || c== ';' || strpart(line, inicio-5, 5) ==? 'endif' + let ind = ind - shiftwidth() + elseif c == '(' || c ==? 'f' " '(' or 'if' + let ind = ind + shiftwidth() + else " c == '=' + " if it is an asignment increase indent + if f == -1 " we don't know yet, find out + let f = CdlAsignment(lnum, strpart(line, 0, inicio)) + end + if f == 1 " formula increase it + let ind = ind + shiftwidth() + end + end + endw + + " CURRENT LINE, if it starts with a closing element, decrease indent + " or if it starts with '=' (asignment), increase indent + if match(thisline, '^\c\s*\(else\|then\|endif\|[);]\)') >= 0 + let ind = ind - shiftwidth() + elseif match(thisline, '^\s*=') >= 0 + if f == -1 " we don't know yet if is an asignment, find out + let f = CdlAsignment(lnum, "") + end + if f == 1 " formula increase it + let ind = ind + shiftwidth() + end + end + + return ind +endfun + +endif diff --git a/indent/ch.vim b/indent/ch.vim new file mode 100644 index 00000000..479ce324 --- /dev/null +++ b/indent/ch.vim @@ -0,0 +1,22 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ch') == -1 + +" Vim indent file +" Language: Ch +" Maintainer: SoftIntegration, Inc. <info@softintegration.com> +" URL: http://www.softintegration.com/download/vim/indent/ch.vim +" Last change: 2006 Apr 30 +" Created based on cpp.vim +" +" Ch is a C/C++ interpreter with many high level extensions + + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" Ch indenting is built-in, thus this is very simple +setlocal cindent + +endif diff --git a/indent/chaiscript.vim b/indent/chaiscript.vim new file mode 100644 index 00000000..49b9bad3 --- /dev/null +++ b/indent/chaiscript.vim @@ -0,0 +1,54 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'chaiscript') == -1 + +" Vim indent file +" Language: ChaiScript +" Maintainer: Jason Turner <lefticus 'at' gmail com> + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetChaiScriptIndent() +setlocal autoindent + +" Only define the function once. +if exists("*GetChaiScriptIndent") + finish +endif + +function! GetChaiScriptIndent() + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + " Add a 'shiftwidth' after lines that start a block: + " lines containing a { + let ind = indent(lnum) + let flag = 0 + let prevline = getline(lnum) + if prevline =~ '^.*{.*' + let ind = ind + shiftwidth() + let flag = 1 + endif + + " Subtract a 'shiftwidth' after lines containing a { followed by a } + " to keep it balanced + if flag == 1 && prevline =~ '.*{.*}.*' + let ind = ind - shiftwidth() + endif + + " Subtract a 'shiftwidth' on lines ending with } + if getline(v:lnum) =~ '^\s*\%(}\)' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/cobol.vim b/indent/cobol.vim new file mode 100644 index 00000000..5cfe2321 --- /dev/null +++ b/indent/cobol.vim @@ -0,0 +1,227 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'cobol') == -1 + +" Vim indent file +" Language: cobol +" Maintainer: Ankit Jain <ajatkj@yahoo.co.in> +" (formerly Tim Pope <vimNOSPAM@tpope.info>) +" $Id: cobol.vim,v 1.1 2007/05/05 18:08:19 vimboss Exp $ +" Last Update: By Ankit Jain on 22.03.2019 +" Ankit Jain 22.03.2019 Changes & fixes: +" Allow chars in 1st 6 columns +" #C22032019 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal expandtab +setlocal indentexpr=GetCobolIndent(v:lnum) +setlocal indentkeys& +setlocal indentkeys+=0<*>,0/,0$,0=01,=~division,=~section,0=~end,0=~then,0=~else,0=~when,*<Return>,. + +" Only define the function once. +if exists("*GetCobolIndent") + finish +endif + +let s:skip = 'getline(".") =~ "^.\\{6\\}[*/$-]\\|\"[^\"]*\""' + +function! s:prevgood(lnum) + " Find a non-blank line above the current line. + " Skip over comments. + let lnum = a:lnum + while lnum > 0 + let lnum = prevnonblank(lnum - 1) + let line = getline(lnum) + if line !~? '^\s*[*/$-]' && line !~? '^.\{6\}[*/$CD-]' + break + endif + endwhile + return lnum +endfunction + +function! s:stripped(lnum) + return substitute(strpart(getline(a:lnum),0,72),'^\s*','','') +endfunction + +function! s:optionalblock(lnum,ind,blocks,clauses) + let ind = a:ind + let clauses = '\c\<\%(\<NOT\s\+\)\@<!\%(NOT\s\+\)\=\%('.a:clauses.'\)' + let begin = '\c-\@<!\<\%('.a:blocks.'\)\>' + let beginfull = begin.'\ze.*\%(\n\%(\s*\%([*/$-].*\)\=\n\)*\)\=\s*\%('.clauses.'\)' + let end = '\c\<end-\%('.a:blocks.'\)\>\|\%(\.\%( \|$\)\)\@=' + let cline = s:stripped(a:lnum) + let line = s:stripped(s:prevgood(a:lnum)) + if cline =~? clauses "&& line !~? '^search\>' + call cursor(a:lnum,1) + let lastclause = searchpair(beginfull,clauses,end,'bWr',s:skip) + if getline(lastclause) =~? clauses && s:stripped(lastclause) !~? '^'.begin + let ind = indent(lastclause) + elseif lastclause > 0 + let ind = indent(lastclause) + shiftwidth() + "let ind = ind + shiftwidth() + endif + elseif line =~? clauses && cline !~? end + let ind = ind + shiftwidth() + endif + return ind +endfunction + +function! GetCobolIndent(lnum) abort + let minshft = 6 + let ashft = minshft + 1 + let bshft = ashft + 4 + " (Obsolete) numbered lines + " #C22032019: Columns 1-6 could have alphabets as well as numbers + "if getline(a:lnum) =~? '^\s*\d\{6\}\%($\|[ */$CD-]\)' + if getline(a:lnum) =~? '^\s*[a-zA-Z0-9]\{6\}\%($\|[ */$CD-]\)' + return 0 + endif + let cline = s:stripped(a:lnum) + " Comments, etc. must start in the 7th column + if cline =~? '^[*/$-]' + return minshft + elseif cline =~# '^[CD]' && indent(a:lnum) == minshft + return minshft + endif + " Divisions, sections, and file descriptions start in area A + if cline =~? '\<\(DIVISION\|SECTION\)\%($\|\.\)' || cline =~? '^[FS]D\>' + return ashft + endif + " Fields + if cline =~? '^0*\(1\|77\)\>' + return ashft + endif + if cline =~? '^\d\+\>' + let cnum = matchstr(cline,'^\d\+\>') + let default = 0 + let step = -1 + while step < 2 + let lnum = a:lnum + while lnum > 0 && lnum < line('$') && lnum > a:lnum - 500 && lnum < a:lnum + 500 + let lnum = step > 0 ? nextnonblank(lnum + step) : prevnonblank(lnum + step) + let line = getline(lnum) + let lindent = indent(lnum) + if line =~? '^\s*\d\+\>' + let num = matchstr(line,'^\s*\zs\d\+\>') + if 0+cnum == num + return lindent + elseif 0+cnum > num && default < lindent + shiftwidth() + let default = lindent + shiftwidth() + endif + elseif lindent < bshft && lindent >= ashft + break + endif + endwhile + let step = step + 2 + endwhile + return default ? default : bshft + endif + let lnum = s:prevgood(a:lnum) + " Hit the start of the file, use "zero" indent. + if lnum == 0 + return ashft + endif + " Initial spaces are ignored + let line = s:stripped(lnum) + let ind = indent(lnum) + " Paragraphs. There may be some false positives. + if cline =~? '^\(\a[A-Z0-9-]*[A-Z0-9]\|\d[A-Z0-9-]*\a\)\.' "\s*$' + if cline !~? '^EXIT\s*\.' && line =~? '\.\s*$' + return ashft + endif + endif + " Paragraphs in the identification division. + "if cline =~? '^\(PROGRAM-ID\|AUTHOR\|INSTALLATION\|' . + "\ 'DATE-WRITTEN\|DATE-COMPILED\|SECURITY\)\>' + "return ashft + "endif + if line =~? '\.$' + " XXX + return bshft + endif + if line =~? '^PERFORM\>' + let perfline = substitute(line, '\c^PERFORM\s*', "", "") + if perfline =~? '^\%(\k\+\s\+TIMES\)\=\s*$' + let ind = ind + shiftwidth() + elseif perfline =~? '^\%(WITH\s\+TEST\|VARYING\|UNTIL\)\>.*[^.]$' + let ind = ind + shiftwidth() + endif + endif + if line =~? '^\%(IF\|THEN\|ELSE\|READ\|EVALUATE\|SEARCH\|SELECT\)\>' + let ind = ind + shiftwidth() + endif + let ind = s:optionalblock(a:lnum,ind,'ADD\|COMPUTE\|DIVIDE\|MULTIPLY\|SUBTRACT','ON\s\+SIZE\s\+ERROR') + let ind = s:optionalblock(a:lnum,ind,'STRING\|UNSTRING\|ACCEPT\|DISPLAY\|CALL','ON\s\+OVERFLOW\|ON\s\+EXCEPTION') + if cline !~? '^AT\s\+END\>' || line !~? '^SEARCH\>' + let ind = s:optionalblock(a:lnum,ind,'DELETE\|REWRITE\|START\|WRITE\|READ','INVALID\s\+KEY\|AT\s\+END\|NO\s\+DATA\|AT\s\+END-OF-PAGE') + endif + if cline =~? '^WHEN\>' + call cursor(a:lnum,1) + " We also search for READ so that contained AT ENDs are skipped + let lastclause = searchpair('\c-\@<!\<\%(SEARCH\|EVALUATE\|READ\)\>','\c\<\%(WHEN\|AT\s\+END\)\>','\c\<END-\%(SEARCH\|EVALUATE\|READ\)\>','bW',s:skip) + let g:foo = s:stripped(lastclause) + if s:stripped(lastclause) =~? '\c\<\%(WHEN\|AT\s\+END\)\>' + "&& s:stripped(lastclause) !~? '^\%(SEARCH\|EVALUATE\|READ\)\>' + let ind = indent(lastclause) + elseif lastclause > 0 + let ind = indent(lastclause) + shiftwidth() + endif + elseif line =~? '^WHEN\>' + let ind = ind + shiftwidth() + endif + "I'm not sure why I had this + "if line =~? '^ELSE\>-\@!' && line !~? '\.$' + "let ind = indent(s:prevgood(lnum)) + "endif + if cline =~? '^\(END\)\>-\@!' + " On lines with just END, 'guess' a simple shift left + let ind = ind - shiftwidth() + elseif cline =~? '^\(END-IF\|THEN\|ELSE\)\>-\@!' + call cursor(a:lnum,indent(a:lnum)) + let match = searchpair('\c-\@<!\<IF\>','\c-\@<!\%(THEN\|ELSE\)\>','\c-\@<!\<END-IF\>\zs','bnW',s:skip) + if match > 0 + let ind = indent(match) + endif + elseif cline =~? '^END-[A-Z]' + let beginword = matchstr(cline,'\c\<END-\zs[A-Z0-9-]\+') + let endword = 'END-'.beginword + let first = 0 + let suffix = '.*\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*' + if beginword =~? '^\%(ADD\|COMPUTE\|DIVIDE\|MULTIPLY\|SUBTRACT\)$' + let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+SIZE\s\+ERROR' + let g:beginword = beginword + let first = 1 + elseif beginword =~? '^\%(STRING\|UNSTRING\)$' + let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+OVERFLOW' + let first = 1 + elseif beginword =~? '^\%(ACCEPT\|DISPLAY\)$' + let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+EXCEPTION' + let first = 1 + elseif beginword ==? 'CALL' + let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=ON\s\+\%(EXCEPTION\|OVERFLOW\)' + let first = 1 + elseif beginword =~? '^\%(DELETE\|REWRITE\|START\|READ\|WRITE\)$' + let first = 1 + let beginword = beginword . suffix . '\<\%(NOT\s\+\)\=\(INVALID\s\+KEY' + if beginword =~? '^READ' + let first = 0 + let beginword = beginword . '\|AT\s\+END\|NO\s\+DATA' + elseif beginword =~? '^WRITE' + let beginword = beginword . '\|AT\s\+END-OF-PAGE' + endif + let beginword = beginword . '\)' + endif + call cursor(a:lnum,indent(a:lnum)) + let match = searchpair('\c-\@<!\<'.beginword.'\>','','\c\<'.endword.'\>\zs','bnW'.(first? 'r' : ''),s:skip) + if match > 0 + let ind = indent(match) + elseif cline =~? '^\(END-\(READ\|EVALUATE\|SEARCH\|PERFORM\)\)\>' + let ind = ind - shiftwidth() + endif + endif + return ind < bshft ? bshft : ind +endfunction + +endif diff --git a/indent/config.vim b/indent/config.vim new file mode 100644 index 00000000..3e59cc5e --- /dev/null +++ b/indent/config.vim @@ -0,0 +1,86 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'config') == -1 + +" Vim indent file +" Language: Autoconf configure.{ac,in} file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 +" TODO: how about nested [()]'s in one line +" what's wrong with '\\\@!'? + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +runtime! indent/sh.vim " will set b:did_indent + +setlocal indentexpr=GetConfigIndent() +setlocal indentkeys=!^F,o,O,=then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done +setlocal nosmartindent + +" Only define the function once. +if exists("*GetConfigIndent") + finish +endif + +" get the offset (indent) of the end of the match of 'regexp' in 'line' +function s:GetOffsetOf(line, regexp) + let end = matchend(a:line, a:regexp) + let width = 0 + let i = 0 + while i < end + if a:line[i] != "\t" + let width = width + 1 + else + let width = width + &ts - (width % &ts) + endif + let i = i + 1 + endwhile + return width +endfunction + +function GetConfigIndent() + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + " where to put this + let ind = GetShIndent() + let line = getline(lnum) + + " if previous line has unmatched, unescaped opening parentheses, + " indent to its position. TODO: not failsafe if multiple ('s + if line =~ '\\\@<!([^)]*$' + let ind = s:GetOffsetOf(line, '\\\@!(') + endif + + " if previous line has unmatched opening bracket, + " indent to its position. TODO: same as above + if line =~ '\[[^]]*$' + let ind = s:GetOffsetOf(line, '\[') + endif + + " if previous line had an unmatched closing parantheses, + " indent to the matching opening parantheses + if line =~ '[^(]\+\\\@<!)$' + call search(')', 'bW') + let lnum = searchpair('\\\@<!(', '', ')', 'bWn') + let ind = indent(lnum) + endif + + " if previous line had an unmatched closing bracket, + " indent to the matching opening bracket + if line =~ '[^[]\+]$' + call search(']', 'bW') + let lnum = searchpair('\[', '', ']', 'bWn') + let ind = indent(lnum) + endif + + return ind +endfunction + +endif diff --git a/indent/context.vim b/indent/context.vim new file mode 100644 index 00000000..16ec0829 --- /dev/null +++ b/indent/context.vim @@ -0,0 +1,40 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'context') == -1 + +" ConTeXt indent file +" Language: ConTeXt typesetting engine +" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com> +" Last Change: 2016 Oct 15 + +if exists("b:did_indent") + finish +endif + +if !get(b:, 'context_metapost', get(g:, 'context_metapost', 1)) + finish +endif + +" Load MetaPost indentation script +runtime! indent/mp.vim + +let s:keepcpo= &cpo +set cpo&vim + +setlocal indentexpr=GetConTeXtIndent() + +let b:undo_indent = "setl indentexpr<" + +function! GetConTeXtIndent() + " Use MetaPost rules inside MetaPost graphic environments + if len(synstack(v:lnum, 1)) > 0 && + \ synIDattr(synstack(v:lnum, 1)[0], "name") ==# 'contextMPGraphic' + return GetMetaPostIndent() + endif + return -1 +endfunc + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vim:sw=2 + +endif diff --git a/indent/cs.vim b/indent/cs.vim new file mode 100644 index 00000000..893f5b80 --- /dev/null +++ b/indent/cs.vim @@ -0,0 +1,77 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'cs') == -1 + +" Vim indent file +" Language: C# +" Maintainer: Nick Jensen <nickspoon@gmail.com> +" Former Maintainers: Aquila Deus +" Johannes Zellner <johannes@zellner.org> +" Last Change: 2018-11-21 +" Filenames: *.cs +" License: Vim (see :h license) +" Repository: https://github.com/nickspoons/vim-cs +" + +" Only load this indent file when no other was loaded. +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +let s:save_cpo = &cpoptions +set cpoptions&vim + + +setlocal indentexpr=GetCSIndent(v:lnum) + +function! s:IsCompilerDirective(line) + return a:line =~? '^\s*#' +endf + +function! s:IsAttributeLine(line) + return a:line =~? '^\s*\[[A-Za-z]' && a:line =~? '\]$' +endf + +function! s:FindPreviousNonCompilerDirectiveLine(start_lnum) + for delta in range(0, a:start_lnum) + let lnum = a:start_lnum - delta + let line = getline(lnum) + let is_directive = s:IsCompilerDirective(line) + if !is_directive + return lnum + endif + endfor + return 0 +endf + +function! GetCSIndent(lnum) abort + " Hit the start of the file, use zero indent. + if a:lnum == 0 + return 0 + endif + + let this_line = getline(a:lnum) + + " Compiler directives use zero indent if so configured. + let is_first_col_macro = s:IsCompilerDirective(this_line) && stridx(&l:cinkeys, '0#') >= 0 + if is_first_col_macro + return cindent(a:lnum) + endif + + let lnum = s:FindPreviousNonCompilerDirectiveLine(a:lnum - 1) + let previous_code_line = getline(lnum) + if s:IsAttributeLine(previous_code_line) + let ind = indent(lnum) + return ind + else + return cindent(a:lnum) + endif +endfunction + +let b:undo_indent = 'setlocal indentexpr<' + +let &cpoptions = s:save_cpo +unlet s:save_cpo + +" vim:et:sw=2:sts=2 + +endif diff --git a/indent/css.vim b/indent/css.vim new file mode 100644 index 00000000..58189a48 --- /dev/null +++ b/indent/css.vim @@ -0,0 +1,88 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'css') == -1 + +" Vim indent file +" Language: CSS +" Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2012-05-30 +" Use of shiftwidth() added by Oleg Zubchenko. + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetCSSIndent() +setlocal indentkeys=0{,0},!^F,o,O +setlocal nosmartindent + +let b:undo_indent = "setl smartindent< indentkeys< indentexpr<" + +if exists("*GetCSSIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +function s:prevnonblanknoncomment(lnum) + let lnum = a:lnum + while lnum > 1 + let lnum = prevnonblank(lnum) + let line = getline(lnum) + if line =~ '\*/' + while lnum > 1 && line !~ '/\*' + let lnum -= 1 + endwhile + if line =~ '^\s*/\*' + let lnum -= 1 + else + break + endif + else + break + endif + endwhile + return lnum +endfunction + +function s:count_braces(lnum, count_open) + let n_open = 0 + let n_close = 0 + let line = getline(a:lnum) + let pattern = '[{}]' + let i = match(line, pattern) + while i != -1 + if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'css\%(Comment\|StringQ\{1,2}\)' + if line[i] == '{' + let n_open += 1 + elseif line[i] == '}' + if n_open > 0 + let n_open -= 1 + else + let n_close += 1 + endif + endif + endif + let i = match(line, pattern, i + 1) + endwhile + return a:count_open ? n_open : n_close +endfunction + +function GetCSSIndent() + let line = getline(v:lnum) + if line =~ '^\s*\*' + return cindent(v:lnum) + endif + + let pnum = s:prevnonblanknoncomment(v:lnum - 1) + if pnum == 0 + return 0 + endif + + return indent(pnum) + s:count_braces(pnum, 1) * shiftwidth() + \ - s:count_braces(v:lnum, 0) * shiftwidth() +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +endif diff --git a/indent/cuda.vim b/indent/cuda.vim new file mode 100644 index 00000000..22552a29 --- /dev/null +++ b/indent/cuda.vim @@ -0,0 +1,19 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'cuda') == -1 + +" Vim indent file +" Language: CUDA +" Maintainer: Bram Moolenaar <Bram@vim.org> +" Last Change: 2008 Nov 29 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" It's just like C indenting +setlocal cindent + +let b:undo_indent = "setl cin<" + +endif diff --git a/indent/dictconf.vim b/indent/dictconf.vim new file mode 100644 index 00000000..3a10fef5 --- /dev/null +++ b/indent/dictconf.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'dictconf') == -1 + +" Vim indent file +" Language: dict(1) configuration file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentkeys=0{,0},!^F,o,O cinwords= autoindent smartindent +setlocal nosmartindent +inoremap <buffer> # X# + +endif diff --git a/indent/dictdconf.vim b/indent/dictdconf.vim new file mode 100644 index 00000000..4338ff88 --- /dev/null +++ b/indent/dictdconf.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'dictdconf') == -1 + +" Vim indent file +" Language: dictd(8) configuration file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentkeys=0{,0},!^F,o,O cinwords= autoindent smartindent +setlocal nosmartindent +inoremap <buffer> # X# + +endif diff --git a/indent/dosbatch.vim b/indent/dosbatch.vim new file mode 100644 index 00000000..f4352ead --- /dev/null +++ b/indent/dosbatch.vim @@ -0,0 +1,63 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'dosbatch') == -1 + +" Vim indent file +" Language: MSDOS batch file (with NT command extensions) +" Maintainer: Ken Takata +" URL: https://github.com/k-takata/vim-dosbatch-indent +" Last Change: 2017 May 10 +" Filenames: *.bat +" License: VIM License + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent +setlocal noautoindent +setlocal indentexpr=GetDosBatchIndent(v:lnum) +setlocal indentkeys=!^F,o,O +setlocal indentkeys+=0=) + +if exists("*GetDosBatchIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function! GetDosBatchIndent(lnum) + let l:prevlnum = prevnonblank(a:lnum-1) + if l:prevlnum == 0 + " top of file + return 0 + endif + + " grab the previous and current line, stripping comments. + let l:prevl = substitute(getline(l:prevlnum), '\c^\s*\%(@\s*\)\?rem\>.*$', '', '') + let l:thisl = getline(a:lnum) + let l:previ = indent(l:prevlnum) + + let l:ind = l:previ + + if l:prevl =~? '^\s*@\=if\>.*(\s*$' || + \ l:prevl =~? '\<do\>\s*(\s*$' || + \ l:prevl =~? '\<else\>\s*\%(if\>.*\)\?(\s*$' || + \ l:prevl =~? '^.*\(&&\|||\)\s*(\s*$' + " previous line opened a block + let l:ind += shiftwidth() + endif + if l:thisl =~ '^\s*)' + " this line closed a block + let l:ind -= shiftwidth() + endif + + return l:ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: ts=8 sw=2 sts=2 + +endif diff --git a/indent/dtd.vim b/indent/dtd.vim new file mode 100644 index 00000000..189182b1 --- /dev/null +++ b/indent/dtd.vim @@ -0,0 +1,329 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'dtd') == -1 + +" Vim indent file +" Language: DTD (Document Type Definition for XML) +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2011-07-08 + +setlocal indentexpr=GetDTDIndent() +setlocal indentkeys=!^F,o,O,> +setlocal nosmartindent + +if exists("*GetDTDIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" TODO: Needs to be adjusted to stop at [, <, and ]. +let s:token_pattern = '^[^[:space:]]\+' + +function s:lex1(input, start, ...) + let pattern = a:0 > 0 ? a:1 : s:token_pattern + let start = matchend(a:input, '^\_s*', a:start) + if start == -1 + return ["", a:start] + endif + let end = matchend(a:input, pattern, start) + if end == -1 + return ["", a:start] + endif + let token = strpart(a:input, start, end - start) + return [token, end] +endfunction + +function s:lex(input, start, ...) + let pattern = a:0 > 0 ? a:1 : s:token_pattern + let info = s:lex1(a:input, a:start, pattern) + while info[0] == '--' + let info = s:lex1(a:input, info[1], pattern) + while info[0] != "" && info[0] != '--' + let info = s:lex1(a:input, info[1], pattern) + endwhile + if info[0] == "" + return info + endif + let info = s:lex1(a:input, info[1], pattern) + endwhile + return info +endfunction + +function s:indent_to_innermost_parentheses(line, end) + let token = '(' + let end = a:end + let parentheses = [end - 1] + while token != "" + let [token, end] = s:lex(a:line, end, '^\%([(),|]\|[A-Za-z0-9_-]\+\|#P\=CDATA\|%[A-Za-z0-9_-]\+;\)[?*+]\=') + if token[0] == '(' + call add(parentheses, end - 1) + elseif token[0] == ')' + if len(parentheses) == 1 + return [-1, end] + endif + call remove(parentheses, -1) + endif + endwhile + return [parentheses[-1] - strridx(a:line, "\n", parentheses[-1]), end] +endfunction + +" TODO: Line and end could be script global (think OO members). +function GetDTDIndent() + if v:lnum == 1 + return 0 + endif + + " Begin by searching back for a <! that isn’t inside a comment. + " From here, depending on what follows immediately after, parse to + " where we’re at to determine what to do. + if search('<!', 'bceW') == 0 + return indent(v:lnum - 1) + endif + let lnum = line('.') + let col = col('.') + let indent = indent('.') + let line = lnum == v:lnum ? getline(lnum) : join(getline(lnum, v:lnum - 1), "\n") + + let [declaration, end] = s:lex1(line, col) + if declaration == "" + return indent + shiftwidth() + elseif declaration == '--' + " We’re looking at a comment. Now, simply determine if the comment is + " terminated or not. If it isn’t, let Vim take care of that using + " 'comments' and 'autoindent'. Otherwise, indent to the first lines level. + while declaration != "" + let [declaration, end] = s:lex(line, end) + if declaration == "-->" + return indent + endif + endwhile + return -1 + elseif declaration == 'ELEMENT' + " Check for element name. If none exists, indent one level. + let [name, end] = s:lex(line, end) + if name == "" + return indent + shiftwidth() + endif + + " Check for token following element name. This can be a specification of + " whether the start or end tag may be omitted. If nothing is found, indent + " one level. + let [token, end] = s:lex(line, end, '^\%([-O(]\|ANY\|EMPTY\)') + let n = 0 + while token =~ '[-O]' && n < 2 + let [token, end] = s:lex(line, end, '^\%([-O(]\|ANY\|EMPTY\)') + let n += 1 + endwhile + if token == "" + return indent + shiftwidth() + endif + + " Next comes the content model. If the token we’ve found isn’t a + " parenthesis it must be either ANY, EMPTY or some random junk. Either + " way, we’re done indenting this element, so set it to that of the first + " line so that the terminating “>†winds up having the same indention. + if token != '(' + return indent + endif + + " Now go through the content model. We need to keep track of the nesting + " of parentheses. As soon as we hit 0 we’re done. If that happens we must + " have a complete content model. Thus set indention to be the same as that + " of the first line so that the terminating “>†winds up having the same + " indention. Otherwise, we’ll indent to the innermost parentheses not yet + " matched. + let [indent_of_innermost, end] = s:indent_to_innermost_parentheses(line, end) + if indent_of_innermost != -1 + return indent_of_innermost + endif + + " Finally, look for any additions and/or exceptions to the content model. + " This is defined by a “+†or “-†followed by another content model + " declaration. + " TODO: Can the “-†be separated by whitespace from the “(â€? + let seen = { '+(': 0, '-(': 0 } + while 1 + let [additions_exceptions, end] = s:lex(line, end, '^[+-](') + if additions_exceptions != '+(' && additions_exceptions != '-(' + let [token, end] = s:lex(line, end) + if token == '>' + return indent + endif + " TODO: Should use s:lex here on getline(v:lnum) and check for >. + return getline(v:lnum) =~ '^\s*>' || count(values(seen), 0) == 0 ? indent : (indent + shiftwidth()) + endif + + " If we’ve seen an addition or exception already and this is of the same + " kind, the user is writing a broken DTD. Time to bail. + if seen[additions_exceptions] + return indent + endif + let seen[additions_exceptions] = 1 + + let [indent_of_innermost, end] = s:indent_to_innermost_parentheses(line, end) + if indent_of_innermost != -1 + return indent_of_innermost + endif + endwhile + elseif declaration == 'ATTLIST' + " Check for element name. If none exists, indent one level. + let [name, end] = s:lex(line, end) + if name == "" + return indent + shiftwidth() + endif + + " Check for any number of attributes. + while 1 + " Check for attribute name. If none exists, indent one level, unless the + " current line is a lone “>â€, in which case we indent to the same level + " as the first line. Otherwise, if the attribute name is “>â€, we have + " actually hit the end of the attribute list, in which case we indent to + " the same level as the first line. + let [name, end] = s:lex(line, end) + if name == "" + " TODO: Should use s:lex here on getline(v:lnum) and check for >. + return getline(v:lnum) =~ '^\s*>' ? indent : (indent + shiftwidth()) + elseif name == ">" + return indent + endif + + " Check for attribute value declaration. If none exists, indent two + " levels. Otherwise, if it’s an enumerated value, check for nested + " parentheses and indent to the innermost one if we don’t reach the end + " of the listc. Otherwise, just continue with looking for the default + " attribute value. + " TODO: Do validation of keywords + " (CDATA|NMTOKEN|NMTOKENS|ID|IDREF|IDREFS|ENTITY|ENTITIES)? + let [value, end] = s:lex(line, end, '^\%((\|[^[:space:]]\+\)') + if value == "" + return indent + shiftwidth() * 2 + elseif value == 'NOTATION' + " If this is a enumerated value based on notations, read another token + " for the actual value. If it doesn’t exist, indent three levels. + " TODO: If validating according to above, value must be equal to '('. + let [value, end] = s:lex(line, end, '^\%((\|[^[:space:]]\+\)') + if value == "" + return indent + shiftwidth() * 3 + endif + endif + + if value == '(' + let [indent_of_innermost, end] = s:indent_to_innermost_parentheses(line, end) + if indent_of_innermost != -1 + return indent_of_innermost + endif + endif + + " Finally look for the attribute’s default value. If non exists, indent + " two levels. + let [default, end] = s:lex(line, end, '^\%("\_[^"]*"\|#\(REQUIRED\|IMPLIED\|FIXED\)\)') + if default == "" + return indent + shiftwidth() * 2 + elseif default == '#FIXED' + " We need to look for the fixed value. If non exists, indent three + " levels. + let [default, end] = s:lex(line, end, '^"\_[^"]*"') + if default == "" + return indent + shiftwidth() * 3 + endif + endif + endwhile + elseif declaration == 'ENTITY' + " Check for entity name. If none exists, indent one level. Otherwise, if + " the name actually turns out to be a percent sign, “%â€, this is a + " parameter entity. Read another token to determine the entity name and, + " again, if none exists, indent one level. + let [name, end] = s:lex(line, end) + if name == "" + return indent + shiftwidth() + elseif name == '%' + let [name, end] = s:lex(line, end) + if name == "" + return indent + shiftwidth() + endif + endif + + " Now check for the entity value. If none exists, indent one level. If it + " does exist, indent to same level as first line, as we’re now done with + " this entity. + " + " The entity value can be a string in single or double quotes (no escapes + " to worry about, as entities are used instead). However, it can also be + " that this is an external unparsed entity. In that case we have to look + " further for (possibly) a public ID and an URI followed by the NDATA + " keyword and the actual notation name. For the public ID and URI, indent + " two levels, if they don’t exist. If the NDATA keyword doesn’t exist, + " indent one level. Otherwise, if the actual notation name doesn’t exist, + " indent two level. If it does, indent to same level as first line, as + " we’re now done with this entity. + let [value, end] = s:lex(line, end) + if value == "" + return indent + shiftwidth() + elseif value == 'SYSTEM' || value == 'PUBLIC' + let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)') + if quoted_string == "" + return indent + shiftwidth() * 2 + endif + + if value == 'PUBLIC' + let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)') + if quoted_string == "" + return indent + shiftwidth() * 2 + endif + endif + + let [ndata, end] = s:lex(line, end) + if ndata == "" + return indent + shiftwidth() + endif + + let [name, end] = s:lex(line, end) + return name == "" ? (indent + shiftwidth() * 2) : indent + else + return indent + endif + elseif declaration == 'NOTATION' + " Check for notation name. If none exists, indent one level. + let [name, end] = s:lex(line, end) + if name == "" + return indent + shiftwidth() + endif + + " Now check for the external ID. If none exists, indent one level. + let [id, end] = s:lex(line, end) + if id == "" + return indent + shiftwidth() + elseif id == 'SYSTEM' || id == 'PUBLIC' + let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\)') + if quoted_string == "" + return indent + shiftwidth() * 2 + endif + + if id == 'PUBLIC' + let [quoted_string, end] = s:lex(line, end, '\%("[^"]\+"\|''[^'']\+''\|>\)') + if quoted_string == "" + " TODO: Should use s:lex here on getline(v:lnum) and check for >. + return getline(v:lnum) =~ '^\s*>' ? indent : (indent + shiftwidth() * 2) + elseif quoted_string == '>' + return indent + endif + endif + endif + + return indent + endif + + " TODO: Processing directives could be indented I suppose. But perhaps it’s + " just as well to let the user decide how to indent them (perhaps extending + " this function to include proper support for whatever processing directive + " language they want to use). + + " Conditional sections are simply passed along to let Vim decide what to do + " (and hence the user). + return -1 +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/dylan.vim b/indent/dylan.vim new file mode 100644 index 00000000..f882f7bd --- /dev/null +++ b/indent/dylan.vim @@ -0,0 +1,94 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'dylan') == -1 + +" Vim indent file +" Language: Dylan +" Version: 0.01 +" Last Change: 2017 Jun 13 +" Maintainer: Brent A. Fulgham <bfulgham@debian.org> + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentkeys+==~begin,=~block,=~case,=~cleanup,=~define,=~end,=~else,=~elseif,=~exception,=~for,=~finally,=~if,=~otherwise,=~select,=~unless,=~while + +" Define the appropriate indent function but only once +setlocal indentexpr=DylanGetIndent() +if exists("*DylanGetIndent") + finish +endif + +function DylanGetIndent() + " Get the line to be indented + let cline = getline(v:lnum) + + " Don't reindent comments on first column + if cline =~ '^/\[/\*]' + return 0 + endif + + "Find the previous non-blank line + let lnum = prevnonblank(v:lnum - 1) + "Use zero indent at the top of the file + if lnum == 0 + return 0 + endif + + let prevline=getline(lnum) + let ind = indent(lnum) + let chg = 0 + + " If previous line was a comment, use its indent + if prevline =~ '^\s*//' + return ind + endif + + " If previous line was a 'define', indent + if prevline =~? '\(^\s*\(begin\|block\|case\|define\|else\|elseif\|for\|finally\|if\|select\|unless\|while\)\|\s*\S*\s*=>$\)' + let chg = shiftwidth() + " local methods indent the shift-width, plus 6 for the 'local' + elseif prevline =~? '^\s*local' + let chg = shiftwidth() + 6 + " If previous line was a let with no closing semicolon, indent + elseif prevline =~? '^\s*let.*[^;]\s*$' + let chg = shiftwidth() + " If previous line opened a parenthesis, and did not close it, indent + elseif prevline =~ '^.*(\s*[^)]*\((.*)\)*[^)]*$' + return = match( prevline, '(.*\((.*)\|[^)]\)*.*$') + 1 + "elseif prevline =~ '^.*(\s*[^)]*\((.*)\)*[^)]*$' + elseif prevline =~ '^[^(]*)\s*$' + " This line closes a parenthesis. Find opening + let curr_line = prevnonblank(lnum - 1) + while curr_line >= 0 + let str = getline(curr_line) + if str !~ '^.*(\s*[^)]*\((.*)\)*[^)]*$' + let curr_line = prevnonblank(curr_line - 1) + else + break + endif + endwhile + if curr_line < 0 + return -1 + endif + let ind = indent(curr_line) + " Although we found the closing parenthesis, make sure this + " line doesn't start with an indentable command: + let curr_str = getline(curr_line) + if curr_str =~? '^\s*\(begin\|block\|case\|define\|else\|elseif\|for\|finally\|if\|select\|unless\|while\)' + let chg = shiftwidth() + endif + endif + + " If a line starts with end, un-indent (even if we just indented!) + if cline =~? '^\s*\(cleanup\|end\|else\|elseif\|exception\|finally\|otherwise\)' + let chg = chg - shiftwidth() + endif + + return ind + chg +endfunction + +" vim:sw=2 tw=130 + +endif diff --git a/indent/eterm.vim b/indent/eterm.vim new file mode 100644 index 00000000..6042815c --- /dev/null +++ b/indent/eterm.vim @@ -0,0 +1,40 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'eterm') == -1 + +" Vim indent file +" Language: Eterm configuration file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetEtermIndent() +setlocal indentkeys=!^F,o,O,=end +setlocal nosmartindent + +if exists("*GetEtermIndent") + finish +endif + +function GetEtermIndent() + let lnum = prevnonblank(v:lnum - 1) + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + + if getline(lnum) =~ '^\s*begin\>' + let ind = ind + shiftwidth() + endif + + if getline(v:lnum) =~ '^\s*end\>' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/falcon.vim b/indent/falcon.vim new file mode 100644 index 00000000..a00d80a7 --- /dev/null +++ b/indent/falcon.vim @@ -0,0 +1,455 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'falcon') == -1 + +" Vim indent file +" Language: Falcon +" Maintainer: Steven Oliver <oliver.steven@gmail.com> +" Website: https://steveno@github.com/steveno/falconpl-vim.git +" Credits: This is, to a great extent, a copy n' paste of ruby.vim. + +" 1. Setup {{{1 +" ============ + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent + +" Setup indent function and when to use it +setlocal indentexpr=FalconGetIndent(v:lnum) +setlocal indentkeys=0{,0},0),0],!^F,o,O,e +setlocal indentkeys+==~case,=~catch,=~default,=~elif,=~else,=~end,=~\" + +" Define the appropriate indent function but only once +if exists("*FalconGetIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" 2. Variables {{{1 +" ============ + +" Regex of syntax group names that are strings AND comments +let s:syng_strcom = '\<falcon\%(String\|StringEscape\|Comment\)\>' + +" Regex of syntax group names that are strings +let s:syng_string = '\<falcon\%(String\|StringEscape\)\>' + +" Regex that defines blocks. +" +" Note that there's a slight problem with this regex and s:continuation_regex. +" Code like this will be matched by both: +" +" method_call do |(a, b)| +" +" The reason is that the pipe matches a hanging "|" operator. +" +let s:block_regex = + \ '\%(\<do:\@!\>\|%\@<!{\)\s*\%(|\s*(*\s*\%([*@&]\=\h\w*,\=\s*\)\%(,\s*(*\s*[*@&]\=\h\w*\s*)*\s*\)*|\)\=\s*\%(#.*\)\=$' + +let s:block_continuation_regex = '^\s*[^])}\t ].*'.s:block_regex + +" Regex that defines continuation lines. +" TODO: this needs to deal with if ...: and so on +let s:continuation_regex = + \ '\%(%\@<![({[\\.,:*/%+]\|\<and\|\<or\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)\s*\%(#.*\)\=$' + +" Regex that defines bracket continuations +let s:bracket_continuation_regex = '%\@<!\%([({[]\)\s*\%(#.*\)\=$' + +" Regex that defines continuation lines, not including (, {, or [. +let s:non_bracket_continuation_regex = '\%([\\.,:*/%+]\|\<and\|\<or\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)\s*\%(#.*\)\=$' + +" Keywords to indent on +let s:falcon_indent_keywords = '^\s*\(case\|catch\|class\|enum\|default\|elif\|else' . + \ '\|for\|function\|if.*"[^"]*:.*"\|if \(\(:\)\@!.\)*$\|loop\|object\|select' . + \ '\|switch\|try\|while\|\w*\s*=\s*\w*([$\)' + +" Keywords to deindent on +let s:falcon_deindent_keywords = '^\s*\(case\|catch\|default\|elif\|else\|end\)' + +" 3. Functions {{{1 +" ============ + +" Check if the character at lnum:col is inside a string, comment, or is ascii. +function s:IsInStringOrComment(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom +endfunction + +" Check if the character at lnum:col is inside a string. +function s:IsInString(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string +endfunction + +" Check if the character at lnum:col is inside a string delimiter +function s:IsInStringDelimiter(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') == 'falconStringDelimiter' +endfunction + +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function s:PrevNonBlankNonString(lnum) + let in_block = 0 + let lnum = prevnonblank(a:lnum) + while lnum > 0 + " Go in and out of blocks comments as necessary. + " If the line isn't empty (with opt. comment) or in a string, end search. + let line = getline(lnum) + if line =~ '^=begin' + if in_block + let in_block = 0 + else + break + endif + elseif !in_block && line =~ '^=end' + let in_block = 1 + elseif !in_block && line !~ '^\s*#.*$' && !(s:IsInStringOrComment(lnum, 1) + \ && s:IsInStringOrComment(lnum, strlen(line))) + break + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return lnum +endfunction + +" Find line above 'lnum' that started the continuation 'lnum' may be part of. +function s:GetMSL(lnum) + " Start on the line we're at and use its indent. + let msl = a:lnum + let msl_body = getline(msl) + let lnum = s:PrevNonBlankNonString(a:lnum - 1) + while lnum > 0 + " If we have a continuation line, or we're in a string, use line as MSL. + " Otherwise, terminate search as we have found our MSL already. + let line = getline(lnum) + + if s:Match(line, s:non_bracket_continuation_regex) && + \ s:Match(msl, s:non_bracket_continuation_regex) + " If the current line is a non-bracket continuation and so is the + " previous one, keep its indent and continue looking for an MSL. + " + " Example: + " method_call one, + " two, + " three + " + let msl = lnum + elseif s:Match(lnum, s:non_bracket_continuation_regex) && + \ (s:Match(msl, s:bracket_continuation_regex) || s:Match(msl, s:block_continuation_regex)) + " If the current line is a bracket continuation or a block-starter, but + " the previous is a non-bracket one, respect the previous' indentation, + " and stop here. + " + " Example: + " method_call one, + " two { + " three + " + return lnum + elseif s:Match(lnum, s:bracket_continuation_regex) && + \ (s:Match(msl, s:bracket_continuation_regex) || s:Match(msl, s:block_continuation_regex)) + " If both lines are bracket continuations (the current may also be a + " block-starter), use the current one's and stop here + " + " Example: + " method_call( + " other_method_call( + " foo + return msl + elseif s:Match(lnum, s:block_regex) && + \ !s:Match(msl, s:continuation_regex) && + \ !s:Match(msl, s:block_continuation_regex) + " If the previous line is a block-starter and the current one is + " mostly ordinary, use the current one as the MSL. + " + " Example: + " method_call do + " something + " something_else + return msl + else + let col = match(line, s:continuation_regex) + 1 + if (col > 0 && !s:IsInStringOrComment(lnum, col)) + \ || s:IsInString(lnum, strlen(line)) + let msl = lnum + else + break + endif + endif + + let msl_body = getline(msl) + let lnum = s:PrevNonBlankNonString(lnum - 1) + endwhile + return msl +endfunction + +" Check if line 'lnum' has more opening brackets than closing ones. +function s:ExtraBrackets(lnum) + let opening = {'parentheses': [], 'braces': [], 'brackets': []} + let closing = {'parentheses': [], 'braces': [], 'brackets': []} + + let line = getline(a:lnum) + let pos = match(line, '[][(){}]', 0) + + " Save any encountered opening brackets, and remove them once a matching + " closing one has been found. If a closing bracket shows up that doesn't + " close anything, save it for later. + while pos != -1 + if !s:IsInStringOrComment(a:lnum, pos + 1) + if line[pos] == '(' + call add(opening.parentheses, {'type': '(', 'pos': pos}) + elseif line[pos] == ')' + if empty(opening.parentheses) + call add(closing.parentheses, {'type': ')', 'pos': pos}) + else + let opening.parentheses = opening.parentheses[0:-2] + endif + elseif line[pos] == '{' + call add(opening.braces, {'type': '{', 'pos': pos}) + elseif line[pos] == '}' + if empty(opening.braces) + call add(closing.braces, {'type': '}', 'pos': pos}) + else + let opening.braces = opening.braces[0:-2] + endif + elseif line[pos] == '[' + call add(opening.brackets, {'type': '[', 'pos': pos}) + elseif line[pos] == ']' + if empty(opening.brackets) + call add(closing.brackets, {'type': ']', 'pos': pos}) + else + let opening.brackets = opening.brackets[0:-2] + endif + endif + endif + + let pos = match(line, '[][(){}]', pos + 1) + endwhile + + " Find the rightmost brackets, since they're the ones that are important in + " both opening and closing cases + let rightmost_opening = {'type': '(', 'pos': -1} + let rightmost_closing = {'type': ')', 'pos': -1} + + for opening in opening.parentheses + opening.braces + opening.brackets + if opening.pos > rightmost_opening.pos + let rightmost_opening = opening + endif + endfor + + for closing in closing.parentheses + closing.braces + closing.brackets + if closing.pos > rightmost_closing.pos + let rightmost_closing = closing + endif + endfor + + return [rightmost_opening, rightmost_closing] +endfunction + +function s:Match(lnum, regex) + let col = match(getline(a:lnum), '\C'.a:regex) + 1 + return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +endfunction + +function s:MatchLast(lnum, regex) + let line = getline(a:lnum) + let col = match(line, '.*\zs' . a:regex) + while col != -1 && s:IsInStringOrComment(a:lnum, col) + let line = strpart(line, 0, col) + let col = match(line, '.*' . a:regex) + endwhile + return col + 1 +endfunction + +" 4. FalconGetIndent Routine {{{1 +" ============ + +function FalconGetIndent(...) + " For the current line, use the first argument if given, else v:lnum + let clnum = a:0 ? a:1 : v:lnum + + " Use zero indent at the top of the file + if clnum == 0 + return 0 + endif + + let line = getline(clnum) + let ind = -1 + + " If we got a closing bracket on an empty line, find its match and indent + " according to it. For parentheses we indent to its column - 1, for the + " others we indent to the containing line's MSL's level. Return -1 if fail. + let col = matchend(line, '^\s*[]})]') + if col > 0 && !s:IsInStringOrComment(clnum, col) + call cursor(clnum, col) + let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) + if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 + if line[col-1]==')' && col('.') != col('$') - 1 + let ind = virtcol('.') - 1 + else + let ind = indent(s:GetMSL(line('.'))) + endif + endif + return ind + endif + + " If we have a deindenting keyword, find its match and indent to its level. + " TODO: this is messy + if s:Match(clnum, s:falcon_deindent_keywords) + call cursor(clnum, 1) + if searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW', + \ s:end_skip_expr) > 0 + let msl = s:GetMSL(line('.')) + let line = getline(line('.')) + + if strpart(line, 0, col('.') - 1) =~ '=\s*$' && + \ strpart(line, col('.') - 1, 2) !~ 'do' + let ind = virtcol('.') - 1 + elseif getline(msl) =~ '=\s*\(#.*\)\=$' + let ind = indent(line('.')) + else + let ind = indent(msl) + endif + endif + return ind + endif + + " If we are in a multi-line string or line-comment, don't do anything to it. + if s:IsInString(clnum, matchend(line, '^\s*') + 1) + return indent('.') + endif + + " Find a non-blank, non-multi-line string line above the current line. + let lnum = s:PrevNonBlankNonString(clnum - 1) + + " If the line is empty and inside a string, use the previous line. + if line =~ '^\s*$' && lnum != prevnonblank(clnum - 1) + return indent(prevnonblank(clnum)) + endif + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + " Set up variables for the previous line. + let line = getline(lnum) + let ind = indent(lnum) + + " If the previous line ended with a block opening, add a level of indent. + if s:Match(lnum, s:block_regex) + return indent(s:GetMSL(lnum)) + shiftwidth() + endif + + " If it contained hanging closing brackets, find the rightmost one, find its + " match and indent according to that. + if line =~ '[[({]' || line =~ '[])}]\s*\%(#.*\)\=$' + let [opening, closing] = s:ExtraBrackets(lnum) + + if opening.pos != -1 + if opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + if col('.') + 1 == col('$') + return ind + shiftwidth() + else + return virtcol('.') + endif + else + let nonspace = matchend(line, '\S', opening.pos + 1) - 1 + return nonspace > 0 ? nonspace : ind + shiftwidth() + endif + elseif closing.pos != -1 + call cursor(lnum, closing.pos + 1) + normal! % + + if s:Match(line('.'), s:falcon_indent_keywords) + return indent('.') + shiftwidth() + else + return indent('.') + endif + else + call cursor(clnum, 0) " FIXME: column was vcol + end + endif + + " If the previous line ended with an "end", match that "end"s beginning's + " indent. + let col = s:Match(lnum, '\%(^\|[^.:@$]\)\<end\>\s*\%(#.*\)\=$') + if col > 0 + call cursor(lnum, col) + if searchpair(s:end_start_regex, '', s:end_end_regex, 'bW', + \ s:end_skip_expr) > 0 + let n = line('.') + let ind = indent('.') + let msl = s:GetMSL(n) + if msl != n + let ind = indent(msl) + end + return ind + endif + end + + let col = s:Match(lnum, s:falcon_indent_keywords) + if col > 0 + call cursor(lnum, col) + let ind = virtcol('.') - 1 + shiftwidth() + " TODO: make this better (we need to count them) (or, if a searchpair + " fails, we know that something is lacking an end and thus we indent a + " level + if s:Match(lnum, s:end_end_regex) + let ind = indent('.') + endif + return ind + endif + + " Set up variables to use and search for MSL to the previous line. + let p_lnum = lnum + let lnum = s:GetMSL(lnum) + + " If the previous line wasn't a MSL and is continuation return its indent. + " TODO: the || s:IsInString() thing worries me a bit. + if p_lnum != lnum + if s:Match(p_lnum, s:non_bracket_continuation_regex) || s:IsInString(p_lnum,strlen(line)) + return ind + endif + endif + + " Set up more variables, now that we know we wasn't continuation bound. + let line = getline(lnum) + let msl_ind = indent(lnum) + + " If the MSL line had an indenting keyword in it, add a level of indent. + " TODO: this does not take into account contrived things such as + " module Foo; class Bar; end + if s:Match(lnum, s:falcon_indent_keywords) + let ind = msl_ind + shiftwidth() + if s:Match(lnum, s:end_end_regex) + let ind = ind - shiftwidth() + endif + return ind + endif + + " If the previous line ended with [*+/.,-=], but wasn't a block ending or a + " closing bracket, indent one extra level. + if s:Match(lnum, s:non_bracket_continuation_regex) && !s:Match(lnum, '^\s*\([\])}]\|end\)') + if lnum == p_lnum + let ind = msl_ind + shiftwidth() + else + let ind = msl_ind + endif + return ind + endif + + return ind +endfunction + +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: set sw=4 sts=4 et tw=80 : + +endif diff --git a/indent/fortran.vim b/indent/fortran.vim new file mode 100644 index 00000000..1fed2974 --- /dev/null +++ b/indent/fortran.vim @@ -0,0 +1,223 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'fortran') == -1 + +" Vim indent file +" Language: Fortran 2008 (and older: Fortran 2003, 95, 90, and 77) +" Version: 47 +" Last Change: 2020 Apr 20 +" Patched By: Eisuke Kawashima +" Maintainer: Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/> +" Usage: For instructions, do :help fortran-indent from Vim +" Credits: +" Useful suggestions were made, in chronological order, by: +" Albert Oliver Serra, Takuya Fujiwara and Philipp Edelmann. + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +let s:cposet=&cpoptions +set cpoptions&vim + +setlocal indentkeys+==~end,=~case,=~if,=~else,=~do,=~where,=~elsewhere,=~select +setlocal indentkeys+==~endif,=~enddo,=~endwhere,=~endselect,=~elseif +setlocal indentkeys+==~type,=~interface,=~forall,=~associate,=~block,=~enum +setlocal indentkeys+==~endforall,=~endassociate,=~endblock,=~endenum +if exists("b:fortran_indent_more") || exists("g:fortran_indent_more") + setlocal indentkeys+==~function,=~subroutine,=~module,=~contains,=~program + setlocal indentkeys+==~endfunction,=~endsubroutine,=~endmodule + setlocal indentkeys+==~endprogram +endif + +" Determine whether this is a fixed or free format source file +" if this hasn't been done yet using the priority: +" buffer-local value +" > global value +" > file extension as in Intel ifort, gcc (gfortran), NAG, Pathscale, and Cray compilers +if !exists("b:fortran_fixed_source") + if exists("fortran_free_source") + " User guarantees free source form + let b:fortran_fixed_source = 0 + elseif exists("fortran_fixed_source") + " User guarantees fixed source form + let b:fortran_fixed_source = 1 + elseif expand("%:e") =~? '^f\%(90\|95\|03\|08\)$' + " Free-form file extension defaults as in Intel ifort, gcc(gfortran), NAG, Pathscale, and Cray compilers + let b:fortran_fixed_source = 0 + elseif expand("%:e") =~? '^\%(f\|f77\|for\)$' + " Fixed-form file extension defaults + let b:fortran_fixed_source = 1 + else + " Modern fortran still allows both fixed and free source form + " Assume fixed source form unless signs of free source form + " are detected in the first five columns of the first s:lmax lines. + " Detection becomes more accurate and time-consuming if more lines + " are checked. Increase the limit below if you keep lots of comments at + " the very top of each file and you have a fast computer. + let s:lmax = 500 + if ( s:lmax > line("$") ) + let s:lmax = line("$") + endif + let b:fortran_fixed_source = 1 + let s:ln=1 + while s:ln <= s:lmax + let s:test = strpart(getline(s:ln),0,5) + if s:test !~ '^[Cc*]' && s:test !~ '^ *[!#]' && s:test =~ '[^ 0-9\t]' && s:test !~ '^[ 0-9]*\t' + let b:fortran_fixed_source = 0 + break + endif + let s:ln = s:ln + 1 + endwhile + endif +endif + +" Define the appropriate indent function but only once +if (b:fortran_fixed_source == 1) + setlocal indentexpr=FortranGetFixedIndent() + if exists("*FortranGetFixedIndent") + finish + endif +else + setlocal indentexpr=FortranGetFreeIndent() + if exists("*FortranGetFreeIndent") + finish + endif +endif + +function FortranGetIndent(lnum) + let ind = indent(a:lnum) + let prevline=getline(a:lnum) + " Strip tail comment + let prevstat=substitute(prevline, '!.*$', '', '') + let prev2line=getline(a:lnum-1) + let prev2stat=substitute(prev2line, '!.*$', '', '') + + "Indent do loops only if they are all guaranteed to be of do/end do type + if exists("b:fortran_do_enddo") || exists("g:fortran_do_enddo") + if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*do\>' + let ind = ind + shiftwidth() + endif + if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*end\s*do\>' + let ind = ind - shiftwidth() + endif + endif + + "Add a shiftwidth to statements following if, else, else if, case, class, + "where, else where, forall, type, interface and associate statements + if prevstat =~? '^\s*\(case\|class\|else\|else\s*if\|else\s*where\)\>' + \ ||prevstat=~? '^\s*\(type\|interface\|associate\|enum\)\>' + \ ||prevstat=~?'^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*\(forall\|where\|block\)\>' + \ ||prevstat=~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>' + let ind = ind + shiftwidth() + " Remove unwanted indent after logical and arithmetic ifs + if prevstat =~? '\<if\>' && prevstat !~? '\<then\>' + let ind = ind - shiftwidth() + endif + " Remove unwanted indent after type( statements + if prevstat =~? '^\s*type\s*(' + let ind = ind - shiftwidth() + endif + endif + + "Indent program units unless instructed otherwise + if !exists("b:fortran_indent_less") && !exists("g:fortran_indent_less") + let prefix='\(\(pure\|impure\|elemental\|recursive\)\s\+\)\{,2}' + let type='\(\(integer\|real\|double\s\+precision\|complex\|logical' + \.'\|character\|type\|class\)\s*\S*\s\+\)\=' + if prevstat =~? '^\s*\(contains\|submodule\|program\)\>' + \ ||prevstat =~? '^\s*'.'module\>\(\s*\procedure\)\@!' + \ ||prevstat =~? '^\s*'.prefix.'subroutine\>' + \ ||prevstat =~? '^\s*'.prefix.type.'function\>' + \ ||prevstat =~? '^\s*'.type.prefix.'function\>' + let ind = ind + shiftwidth() + endif + if getline(v:lnum) =~? '^\s*contains\>' + \ ||getline(v:lnum)=~? '^\s*end\s*' + \ .'\(function\|subroutine\|module\|submodule\|program\)\>' + let ind = ind - shiftwidth() + endif + endif + + "Subtract a shiftwidth from else, else if, elsewhere, case, class, end if, + " end where, end select, end forall, end interface, end associate, + " end enum, end type, end block and end type statements + if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*' + \. '\(else\|else\s*if\|else\s*where\|case\|class\|' + \. 'end\s*\(if\|where\|select\|interface\|' + \. 'type\|forall\|associate\|enum\|block\)\)\>' + let ind = ind - shiftwidth() + " Fix indent for case statement immediately after select + if prevstat =~? '\<select\s\+\(case\|type\)\>' + let ind = ind + shiftwidth() + endif + endif + + "First continuation line + if prevstat =~ '&\s*$' && prev2stat !~ '&\s*$' + let ind = ind + shiftwidth() + endif + "Line after last continuation line + if prevstat !~ '&\s*$' && prev2stat =~ '&\s*$' && prevstat !~? '\<then\>' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +function FortranGetFreeIndent() + "Find the previous non-blank line + let lnum = prevnonblank(v:lnum - 1) + + "Use zero indent at the top of the file + if lnum == 0 + return 0 + endif + + let ind=FortranGetIndent(lnum) + return ind +endfunction + +function FortranGetFixedIndent() + let currline=getline(v:lnum) + "Don't indent comments, continuation lines and labelled lines + if strpart(currline,0,6) =~ '[^ \t]' + let ind = indent(v:lnum) + return ind + endif + + "Find the previous line which is not blank, not a comment, + "not a continuation line, and does not have a label + let lnum = v:lnum - 1 + while lnum > 0 + let prevline=getline(lnum) + if (prevline =~ "^[C*!]") || (prevline =~ "^\s*$") + \ || (strpart(prevline,5,1) !~ "[ 0]") + " Skip comments, blank lines and continuation lines + let lnum = lnum - 1 + else + let test=strpart(prevline,0,5) + if test =~ "[0-9]" + " Skip lines with statement numbers + let lnum = lnum - 1 + else + break + endif + endif + endwhile + + "First line must begin at column 7 + if lnum == 0 + return 6 + endif + + let ind=FortranGetIndent(lnum) + return ind +endfunction + +let &cpoptions=s:cposet +unlet s:cposet + +" vim:sw=2 tw=130 + +endif diff --git a/indent/framescript.vim b/indent/framescript.vim new file mode 100644 index 00000000..d7a7b0e1 --- /dev/null +++ b/indent/framescript.vim @@ -0,0 +1,45 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'framescript') == -1 + +" Vim indent file +" Language: FrameScript +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2008-07-19 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetFrameScriptIndent() +setlocal indentkeys=!^F,o,O,0=~Else,0=~EndIf,0=~EndLoop,0=~EndSub +setlocal nosmartindent + +if exists("*GetFrameScriptIndent") + finish +endif + +function GetFrameScriptIndent() + let lnum = prevnonblank(v:lnum - 1) + + if lnum == 0 + return 0 + endif + + if getline(v:lnum) =~ '^\s*\*' + return cindent(v:lnum) + endif + + let ind = indent(lnum) + + if getline(lnum) =~? '^\s*\%(If\|Loop\|Sub\)' + let ind = ind + shiftwidth() + endif + + if getline(v:lnum) =~? '^\s*\%(Else\|End\%(If\|Loop\|Sub\)\)' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/gitolite.vim b/indent/gitolite.vim new file mode 100644 index 00000000..acde56c9 --- /dev/null +++ b/indent/gitolite.vim @@ -0,0 +1,53 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'gitolite') == -1 + +" Vim indent file +" Language: gitolite configuration +" URL: https://github.com/sitaramc/gitolite/blob/master/contrib/vim/indent/gitolite.vim +" (https://raw.githubusercontent.com/sitaramc/gitolite/master/contrib/vim/indent/gitolite.vim) +" Maintainer: Sitaram Chamarty <sitaramc@gmail.com> +" (former Maintainer: Teemu Matilainen <teemu.matilainen@iki.fi>) +" Last Change: 2017 Oct 05 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetGitoliteIndent() +setlocal indentkeys=o,O,*<Return>,!^F,=repo,\",= + +" Only define the function once. +if exists("*GetGitoliteIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function! GetGitoliteIndent() + let prevln = prevnonblank(v:lnum-1) + let pline = getline(prevln) + let cline = getline(v:lnum) + + if cline =~ '^\s*\(C\|R\|RW\|RW+\|RWC\|RW+C\|RWD\|RW+D\|RWCD\|RW+CD\|-\)[ \t=]' + return shiftwidth() + elseif cline =~ '^\s*config\s' + return shiftwidth() + elseif cline =~ '^\s*option\s' + return shiftwidth() + elseif pline =~ '^\s*repo\s' && cline =~ '^\s*\(#.*\)\?$' + return shiftwidth() + elseif cline =~ '^\s*#' + return indent(prevln) + elseif cline =~ '^\s*$' + return -1 + else + return 0 + endif +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/hog.vim b/indent/hog.vim new file mode 100644 index 00000000..20e152b3 --- /dev/null +++ b/indent/hog.vim @@ -0,0 +1,81 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'hog') == -1 + +" Vim indent file +" Language: hog (Snort.conf) +" Maintainer: Victor Roemer, <vroemer@badsec.org> +" Last Change: Mar 7, 2013 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 +let b:undo_indent = 'setlocal smartindent< indentexpr< indentkeys<' + +setlocal nosmartindent +setlocal indentexpr=GetHogIndent() +setlocal indentkeys+=!^F,o,O,0# + +" Only define the function once. +if exists("*GetHogIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +let s:syn_blocks = '\<SnortRuleTypeBody\>' + +function s:IsInBlock(lnum) + return synIDattr(synID(a:lnum, 1, 1), 'name') =~ s:syn_blocks +endfunction + +function GetHogIndent() + let prevlnum = prevnonblank(v:lnum-1) + + " Comment blocks have identical indent + if getline(v:lnum) =~ '^\s*#' && getline(prevlnum) =~ '^\s*#' + return indent(prevlnum) + endif + + " Ignore comment lines when calculating indent + while getline(prevlnum) =~ '^\s*#' + let prevlnum = prevnonblank(prevlnum-1) + if !prevlnum + return previndent + endif + endwhile + + " Continuation of a line that wasn't indented + let prevline = getline(prevlnum) + if prevline =~ '^\k\+.*\\\s*$' + return shiftwidth() + endif + + " Continuation of a line that was indented + if prevline =~ '\k\+.*\\\s*$' + return indent(prevlnum) + endif + + " Indent the next line if previous line contained a start of a block + " definition ('{' or '('). + if prevline =~ '^\k\+[^#]*{}\@!\s*$' " TODO || prevline =~ '^\k\+[^#]*()\@!\s*$' + return shiftwidth() + endif + + " Match inside of a block + if s:IsInBlock(v:lnum) + if prevline =~ "^\k\+.*$" + return shiftwidth() + else + return indent(prevlnum) + endif + endif + + return 0 +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/j.vim b/indent/j.vim new file mode 100644 index 00000000..550fae8a --- /dev/null +++ b/indent/j.vim @@ -0,0 +1,54 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'j') == -1 + +" Vim indent file +" Language: J +" Maintainer: David Bürgin <dbuergin@gluet.ch> +" URL: https://gitlab.com/glts/vim-j +" Last Change: 2015-01-11 + +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetJIndent() +setlocal indentkeys-=0{,0},:,0# +setlocal indentkeys+=0),0<:>,=case.,=catch.,=catchd.,=catcht.,=do.,=else.,=elseif.,=end.,=fcase. + +let b:undo_indent = 'setlocal indentkeys< indentexpr<' + +if exists('*GetJIndent') + finish +endif + +" If g:j_indent_definitions is true, the bodies of explicit definitions of +" adverbs, conjunctions, and verbs will be indented. Default is false (0). +if !exists('g:j_indent_definitions') + let g:j_indent_definitions = 0 +endif + +function GetJIndent() abort + let l:prevlnum = prevnonblank(v:lnum - 1) + if l:prevlnum == 0 + return 0 + endif + let l:indent = indent(l:prevlnum) + let l:prevline = getline(l:prevlnum) + if l:prevline =~# '^\s*\%(case\|catch[dt]\=\|do\|else\%(if\)\=\|fcase\|for\%(_\a\k*\)\=\|if\|select\|try\|whil\%(e\|st\)\)\.\%(\%(\<end\.\)\@!.\)*$' + " Increase indentation after an initial control word that starts or + " continues a block and is not terminated by "end." + let l:indent += shiftwidth() + elseif g:j_indent_definitions && (l:prevline =~# '\<\%([1-4]\|13\|adverb\|conjunction\|verb\|monad\|dyad\)\s\+\%(:\s*0\|def\s\+0\|define\)\>' || l:prevline =~# '^\s*:\s*$') + " Increase indentation in explicit definitions of adverbs, conjunctions, + " and verbs + let l:indent += shiftwidth() + endif + " Decrease indentation in lines that start with either control words that + " continue or end a block, or the special items ")" and ":" + if getline(v:lnum) =~# '^\s*\%()\|:\|\%(case\|catch[dt]\=\|do\|else\%(if\)\=\|end\|fcase\)\.\)' + let l:indent -= shiftwidth() + endif + return l:indent +endfunction + +endif diff --git a/indent/java.vim b/indent/java.vim new file mode 100644 index 00000000..99203420 --- /dev/null +++ b/indent/java.vim @@ -0,0 +1,154 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'java') == -1 + +" Vim indent file +" Language: Java +" Previous Maintainer: Toby Allsopp <toby.allsopp@peace.com> +" Current Maintainer: Hong Xu <hong@topbug.net> +" Homepage: http://www.vim.org/scripts/script.php?script_id=3899 +" https://github.com/xuhdev/indent-java.vim +" Last Change: 2016 Mar 7 +" Version: 1.1 +" License: Same as Vim. +" Copyright (c) 2012-2016 Hong Xu +" Before 2012, this file was maintained by Toby Allsopp. + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" Indent Java anonymous classes correctly. +setlocal cindent cinoptions& cinoptions+=j1 + +" The "extends" and "implements" lines start off with the wrong indent. +setlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements + +" Set the function to do the work. +setlocal indentexpr=GetJavaIndent() + +let b:undo_indent = "set cin< cino< indentkeys< indentexpr<" + +" Only define the function once. +if exists("*GetJavaIndent") + finish +endif + +let s:keepcpo= &cpo +set cpo&vim + +function! SkipJavaBlanksAndComments(startline) + let lnum = a:startline + while lnum > 1 + let lnum = prevnonblank(lnum) + if getline(lnum) =~ '\*/\s*$' + while getline(lnum) !~ '/\*' && lnum > 1 + let lnum = lnum - 1 + endwhile + if getline(lnum) =~ '^\s*/\*' + let lnum = lnum - 1 + else + break + endif + elseif getline(lnum) =~ '^\s*//' + let lnum = lnum - 1 + else + break + endif + endwhile + return lnum +endfunction + +function GetJavaIndent() + + " Java is just like C; use the built-in C indenting and then correct a few + " specific cases. + let theIndent = cindent(v:lnum) + + " If we're in the middle of a comment then just trust cindent + if getline(v:lnum) =~ '^\s*\*' + return theIndent + endif + + " find start of previous line, in case it was a continuation line + let lnum = SkipJavaBlanksAndComments(v:lnum - 1) + + " If the previous line starts with '@', we should have the same indent as + " the previous one + if getline(lnum) =~ '^\s*@.*$' + return indent(lnum) + endif + + let prev = lnum + while prev > 1 + let next_prev = SkipJavaBlanksAndComments(prev - 1) + if getline(next_prev) !~ ',\s*$' + break + endif + let prev = next_prev + endwhile + + " Try to align "throws" lines for methods and "extends" and "implements" for + " classes. + if getline(v:lnum) =~ '^\s*\(throws\|extends\|implements\)\>' + \ && getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>' + let theIndent = theIndent + shiftwidth() + endif + + " correct for continuation lines of "throws", "implements" and "extends" + let cont_kw = matchstr(getline(prev), + \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$') + if strlen(cont_kw) > 0 + let amount = strlen(cont_kw) + 1 + if getline(lnum) !~ ',\s*$' + let theIndent = theIndent - (amount + shiftwidth()) + if theIndent < 0 + let theIndent = 0 + endif + elseif prev == lnum + let theIndent = theIndent + amount + if cont_kw ==# 'throws' + let theIndent = theIndent + shiftwidth() + endif + endif + elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>' + \ && (getline(prev) =~ '{\s*$' + \ || getline(v:lnum) =~ '^\s*{\s*$') + let theIndent = theIndent - shiftwidth() + endif + + " When the line starts with a }, try aligning it with the matching {, + " skipping over "throws", "extends" and "implements" clauses. + if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' + call cursor(v:lnum, 1) + silent normal! % + let lnum = line('.') + if lnum < v:lnum + while lnum > 1 + let next_lnum = SkipJavaBlanksAndComments(lnum - 1) + if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>' + \ && getline(next_lnum) !~ ',\s*$' + break + endif + let lnum = prevnonblank(next_lnum) + endwhile + return indent(lnum) + endif + endif + + " Below a line starting with "}" never indent more. Needed for a method + " below a method with an indented "throws" clause. + let lnum = SkipJavaBlanksAndComments(v:lnum - 1) + if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent + let theIndent = indent(lnum) + endif + + return theIndent +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vi: sw=2 et + +endif diff --git a/indent/jsp.vim b/indent/jsp.vim new file mode 100644 index 00000000..613496bc --- /dev/null +++ b/indent/jsp.vim @@ -0,0 +1,21 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'jsp') == -1 + +" Vim filetype indent file +" Language: JSP files +" Maintainer: David Fishburn <fishburn@ianywhere.com> +" Version: 1.0 +" Last Change: Wed Nov 08 2006 11:08:05 AM + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" If there has been no specific JSP indent script created, +" use the default html indent script which will handle +" html, javascript and most of the JSP constructs. +runtime! indent/html.vim + + + +endif diff --git a/indent/ld.vim b/indent/ld.vim new file mode 100644 index 00000000..d5c90854 --- /dev/null +++ b/indent/ld.vim @@ -0,0 +1,88 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ld') == -1 + +" Vim indent file +" Language: ld(1) script +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetLDIndent() +setlocal indentkeys=0{,0},!^F,o,O +setlocal nosmartindent + +if exists("*GetLDIndent") + finish +endif + +function s:prevnonblanknoncomment(lnum) + let lnum = a:lnum + while lnum > 1 + let lnum = prevnonblank(lnum) + let line = getline(lnum) + if line =~ '\*/' + while lnum > 1 && line !~ '/\*' + let lnum -= 1 + endwhile + if line =~ '^\s*/\*' + let lnum -= 1 + else + break + endif + else + break + endif + endwhile + return lnum +endfunction + +function s:count_braces(lnum, count_open) + let n_open = 0 + let n_close = 0 + let line = getline(a:lnum) + let pattern = '[{}]' + let i = match(line, pattern) + while i != -1 + if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'ld\%(Comment\|String\)' + if line[i] == '{' + let n_open += 1 + elseif line[i] == '}' + if n_open > 0 + let n_open -= 1 + else + let n_close += 1 + endif + endif + endif + let i = match(line, pattern, i + 1) + endwhile + return a:count_open ? n_open : n_close +endfunction + +function GetLDIndent() + let line = getline(v:lnum) + if line =~ '^\s*\*' + return cindent(v:lnum) + elseif line =~ '^\s*}' + return indent(v:lnum) - shiftwidth() + endif + + let pnum = s:prevnonblanknoncomment(v:lnum - 1) + if pnum == 0 + return 0 + endif + + let ind = indent(pnum) + s:count_braces(pnum, 1) * shiftwidth() + + let pline = getline(pnum) + if pline =~ '}\s*$' + let ind -= (s:count_braces(pnum, 0) - (pline =~ '^\s*}' ? 1 : 0)) * shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/lifelines.vim b/indent/lifelines.vim new file mode 100644 index 00000000..b0c16ba5 --- /dev/null +++ b/indent/lifelines.vim @@ -0,0 +1,28 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'lifelines') == -1 + +" Vim indent file +" Language: LifeLines +" Maintainer: Patrick Texier <p.texier@orsennes.com> +" Location: <http://patrick.texier.free.fr/vim/indent/lifelines.vim> +" Last Change: 2010 May 7 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" LifeLines uses cindent without ; line terminator, C functions +" declarations, C keywords, C++ formating +setlocal cindent +setlocal cinwords="" +setlocal cinoptions+=+0 +setlocal cinoptions+=p0 +setlocal cinoptions+=i0 +setlocal cinoptions+=t0 +setlocal cinoptions+=*500 + +let b:undo_indent = "setl cin< cino< cinw<" +" vim: ts=8 sw=4 + +endif diff --git a/indent/liquid.vim b/indent/liquid.vim new file mode 100644 index 00000000..60f9c603 --- /dev/null +++ b/indent/liquid.vim @@ -0,0 +1,67 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'liquid') == -1 + +" Vim indent file +" Language: Liquid +" Maintainer: Tim Pope <vimNOSPAM@tpope.org> +" Last Change: 2017 Jun 13 + +if exists('b:did_indent') + finish +endif + +set indentexpr= +if exists('b:liquid_subtype') + exe 'runtime! indent/'.b:liquid_subtype.'.vim' +else + runtime! indent/html.vim +endif +unlet! b:did_indent + +if &l:indentexpr == '' + if &l:cindent + let &l:indentexpr = 'cindent(v:lnum)' + else + let &l:indentexpr = 'indent(prevnonblank(v:lnum-1))' + endif +endif +let b:liquid_subtype_indentexpr = &l:indentexpr + +let b:did_indent = 1 + +setlocal indentexpr=GetLiquidIndent() +setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],o,O,!^F,=end,=endif,=endunless,=endifchanged,=endcase,=endfor,=endtablerow,=endcapture,=else,=elsif,=when,=empty + +" Only define the function once. +if exists('*GetLiquidIndent') + finish +endif + +function! s:count(string,pattern) + let string = substitute(a:string,'\C'.a:pattern,"\n",'g') + return strlen(substitute(string,"[^\n]",'','g')) +endfunction + +function! GetLiquidIndent(...) + if a:0 && a:1 == '.' + let v:lnum = line('.') + elseif a:0 && a:1 =~ '^\d' + let v:lnum = a:1 + endif + let vcol = col('.') + call cursor(v:lnum,1) + exe "let ind = ".b:liquid_subtype_indentexpr + let lnum = prevnonblank(v:lnum-1) + let line = getline(lnum) + let cline = getline(v:lnum) + let line = substitute(line,'\C^\%(\s*{%\s*end\w*\s*%}\)\+','','') + let line .= matchstr(cline,'\C^\%(\s*{%\s*end\w*\s*%}\)\+') + let cline = substitute(cline,'\C^\%(\s*{%\s*end\w*\s*%}\)\+','','') + let sw = shiftwidth() + let ind += sw * s:count(line,'{%\s*\%(if\|elsif\|else\|unless\|ifchanged\|case\|when\|for\|empty\|tablerow\|capture\)\>') + let ind -= sw * s:count(line,'{%\s*end\%(if\|unless\|ifchanged\|case\|for\|tablerow\|capture\)\>') + let ind -= sw * s:count(cline,'{%\s*\%(elsif\|else\|when\|empty\)\>') + let ind -= sw * s:count(cline,'{%\s*end\w*$') + return ind +endfunction + +endif diff --git a/indent/lisp.vim b/indent/lisp.vim new file mode 100644 index 00000000..13e0558a --- /dev/null +++ b/indent/lisp.vim @@ -0,0 +1,19 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'lisp') == -1 + +" Vim indent file +" Language: Lisp +" Maintainer: Sergey Khorev <sergey.khorev@gmail.com> +" URL: http://sites.google.com/site/khorser/opensource/vim +" Last Change: 2012 Jan 10 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal ai nosi + +let b:undo_indent = "setl ai< si<" + +endif diff --git a/indent/logtalk.vim b/indent/logtalk.vim new file mode 100644 index 00000000..3ca14707 --- /dev/null +++ b/indent/logtalk.vim @@ -0,0 +1,68 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'logtalk') == -1 + +" Maintainer: Paulo Moura <pmoura@logtalk.org> +" Revised on: 2018.08.04 +" Language: Logtalk + +" This Logtalk indent file is a modified version of the Prolog +" indent file written by Gergely Kontra + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +let b:did_indent = 1 + +setlocal indentexpr=GetLogtalkIndent() +setlocal indentkeys-=:,0# +setlocal indentkeys+=0%,-,0;,>,0) + +" Only define the function once. +if exists("*GetLogtalkIndent") + finish +endif + +function! GetLogtalkIndent() + " Find a non-blank line above the current line. + let pnum = prevnonblank(v:lnum - 1) + " Hit the start of the file, use zero indent. + if pnum == 0 + return 0 + endif + let line = getline(v:lnum) + let pline = getline(pnum) + + let ind = indent(pnum) + " Previous line was comment -> use previous line's indent + if pline =~ '^\s*%' + retu ind + endif + " Check for entity opening directive on previous line + if pline =~ '^\s*:-\s\(object\|protocol\|category\)\ze(.*,$' + let ind = ind + shiftwidth() + " Check for clause head on previous line + elseif pline =~ ':-\s*\(%.*\)\?$' + let ind = ind + shiftwidth() + " Check for grammar rule head on previous line + elseif pline =~ '-->\s*\(%.*\)\?$' + let ind = ind + shiftwidth() + " Check for entity closing directive on previous line + elseif pline =~ '^\s*:-\send_\(object\|protocol\|category\)\.\(%.*\)\?$' + let ind = ind - shiftwidth() + " Check for end of clause on previous line + elseif pline =~ '\.\s*\(%.*\)\?$' + let ind = ind - shiftwidth() + endif + " Check for opening conditional on previous line + if pline =~ '^\s*\([(;]\|->\)' && pline !~ '\.\s*\(%.*\)\?$' && pline !~ '^.*\([)][,]\s*\(%.*\)\?$\)' + let ind = ind + shiftwidth() + endif + " Check for closing an unclosed paren, or middle ; or -> + if line =~ '^\s*\([);]\|->\)' + let ind = ind - shiftwidth() + endif + return ind +endfunction + +endif diff --git a/indent/mail.vim b/indent/mail.vim new file mode 100644 index 00000000..6ecf607f --- /dev/null +++ b/indent/mail.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mail') == -1 + +" Vim indent file +" Language: Mail +" Maintainer: Bram Moolenaar +" Last Change: 2009 Jun 03 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" What works best is auto-indenting, disable other indenting. +" For formatting see the ftplugin. +setlocal autoindent nosmartindent nocindent indentexpr= + +endif diff --git a/indent/mf.vim b/indent/mf.vim new file mode 100644 index 00000000..b3f1dea8 --- /dev/null +++ b/indent/mf.vim @@ -0,0 +1,10 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mf') == -1 + +" METAFONT indent file +" Language: METAFONT +" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com> +" Last Change: 2016 Oct 1 + +runtime! indent/mp.vim + +endif diff --git a/indent/mp.vim b/indent/mp.vim new file mode 100644 index 00000000..76e9df22 --- /dev/null +++ b/indent/mp.vim @@ -0,0 +1,364 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mp') == -1 + +" MetaPost indent file +" Language: MetaPost +" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com> +" Former Maintainers: Eugene Minkovskii <emin@mccme.ru> +" Last Change: 2016 Oct 2, 4:13pm +" Version: 0.2 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetMetaPostIndent() +setlocal indentkeys+==end,=else,=fi,=fill,0),0] + +let b:undo_indent = "setl indentkeys< indentexpr<" + +" Only define the function once. +if exists("*GetMetaPostIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +function GetMetaPostIndent() + let ignorecase_save = &ignorecase + try + let &ignorecase = 0 + return GetMetaPostIndentIntern() + finally + let &ignorecase = ignorecase_save + endtry +endfunc + +" Regexps {{{ +" Note: the next three variables are made global so that a user may add +" further keywords. +" +" Example: +" +" Put these in ~/.vim/after/indent/mp.vim +" +" let g:mp_open_tag .= '\|\<begintest\>' +" let g:mp_close_tag .= '\|\<endtest\>' + +" Expressions starting indented blocks +let g:mp_open_tag = '' + \ . '\<if\>' + \ . '\|\<else\%[if]\>' + \ . '\|\<for\%(\|ever\|suffixes\)\>' + \ . '\|\<begingroup\>' + \ . '\|\<\%(\|var\|primary\|secondary\|tertiary\)def\>' + \ . '\|^\s*\<begin\%(fig\|graph\|glyph\|char\|logochar\)\>' + \ . '\|[([{]' + +" Expressions ending indented blocks +let g:mp_close_tag = '' + \ . '\<fi\>' + \ . '\|\<else\%[if]\>' + \ . '\|\<end\%(\|for\|group\|def\|fig\|char\|glyph\|graph\)\>' + \ . '\|[)\]}]' + +" Statements that may span multiple lines and are ended by a semicolon. To +" keep this list short, statements that are unlikely to be very long or are +" not very common (e.g., keywords like `interim` or `showtoken`) are not +" included. +" +" The regex for assignments and equations (the last branch) is tricky, because +" it must not match things like `for i :=`, `if a=b`, `def...=`, etc... It is +" not perfect, but it works reasonably well. +let g:mp_statement = '' + \ . '\<\%(\|un\|cut\)draw\>' + \ . '\|\<\%(\|un\)fill\%[draw]\>' + \ . '\|\<draw\%(dbl\)\=arrow\>' + \ . '\|\<clip\>' + \ . '\|\<addto\>' + \ . '\|\<save\>' + \ . '\|\<setbounds\>' + \ . '\|\<message\>' + \ . '\|\<errmessage\>' + \ . '\|\<errhelp\>' + \ . '\|\<fontmapline\>' + \ . '\|\<pickup\>' + \ . '\|\<show\>' + \ . '\|\<special\>' + \ . '\|\<write\>' + \ . '\|\%(^\|;\)\%([^;=]*\%('.g:mp_open_tag.'\)\)\@!.\{-}:\==' + +" A line ends with zero or more spaces, possibly followed by a comment. +let s:eol = '\s*\%($\|%\)' +" }}} + +" Auxiliary functions {{{ +" Returns 1 if (0-based) position immediately preceding `pos` in `line` is +" inside a string or a comment; returns 0 otherwise. + +" This is the function that is called more often when indenting, so it is +" critical that it is efficient. The method we use is significantly faster +" than using syntax attributes, and more general (it does not require +" syntax_items). It is also faster than using a single regex matching an even +" number of quotes. It helps that MetaPost strings cannot span more than one +" line and cannot contain escaped quotes. +function! s:CommentOrString(line, pos) + let in_string = 0 + let q = stridx(a:line, '"') + let c = stridx(a:line, '%') + while q >= 0 && q < a:pos + if c >= 0 && c < q + if in_string " Find next percent symbol + let c = stridx(a:line, '%', q + 1) + else " Inside comment + return 1 + endif + endif + let in_string = 1 - in_string + let q = stridx(a:line, '"', q + 1) " Find next quote + endwhile + return in_string || (c >= 0 && c <= a:pos) +endfunction + +" Find the first non-comment non-blank line before the current line. +function! s:PrevNonBlankNonComment(lnum) + let l:lnum = prevnonblank(a:lnum - 1) + while getline(l:lnum) =~# '^\s*%' + let l:lnum = prevnonblank(l:lnum - 1) + endwhile + return l:lnum +endfunction + +" Returns true if the last tag appearing in the line is an open tag; returns +" false otherwise. +function! s:LastTagIsOpen(line) + let o = s:LastValidMatchEnd(a:line, g:mp_open_tag, 0) + if o == - 1 | return v:false | endif + return s:LastValidMatchEnd(a:line, g:mp_close_tag, o) < 0 +endfunction + +" A simple, efficient and quite effective heuristics is used to test whether +" a line should cause the next line to be indented: count the "opening tags" +" (if, for, def, ...) in the line, count the "closing tags" (endif, endfor, +" ...) in the line, and compute the difference. We call the result the +" "weight" of the line. If the weight is positive, then the next line should +" most likely be indented. Note that `else` and `elseif` are both opening and +" closing tags, so they "cancel out" in almost all cases, the only exception +" being a leading `else[if]`, which is counted as an opening tag, but not as +" a closing tag (so that, for instance, a line containing a single `else:` +" will have weight equal to one, not zero). We do not treat a trailing +" `else[if]` in any special way, because lines ending with an open tag are +" dealt with separately before this function is called (see +" GetMetaPostIndentIntern()). +" +" Example: +" +" forsuffixes $=a,b: if x.$ = y.$ : draw else: fill fi +" % This line will be indented because |{forsuffixes,if,else}| > |{else,fi}| (3 > 2) +" endfor + +function! s:Weight(line) + let [o, i] = [0, s:ValidMatchEnd(a:line, g:mp_open_tag, 0)] + while i > 0 + let o += 1 + let i = s:ValidMatchEnd(a:line, g:mp_open_tag, i) + endwhile + let [c, i] = [0, matchend(a:line, '^\s*\<else\%[if]\>')] " Skip a leading else[if] + let i = s:ValidMatchEnd(a:line, g:mp_close_tag, i) + while i > 0 + let c += 1 + let i = s:ValidMatchEnd(a:line, g:mp_close_tag, i) + endwhile + return o - c +endfunction + +" Similar to matchend(), but skips strings and comments. +" line: a String +function! s:ValidMatchEnd(line, pat, start) + let i = matchend(a:line, a:pat, a:start) + while i > 0 && s:CommentOrString(a:line, i) + let i = matchend(a:line, a:pat, i) + endwhile + return i +endfunction + +" Like s:ValidMatchEnd(), but returns the end position of the last (i.e., +" rightmost) match. +function! s:LastValidMatchEnd(line, pat, start) + let last_found = -1 + let i = matchend(a:line, a:pat, a:start) + while i > 0 + if !s:CommentOrString(a:line, i) + let last_found = i + endif + let i = matchend(a:line, a:pat, i) + endwhile + return last_found +endfunction + +function! s:DecreaseIndentOnClosingTag(curr_indent) + let cur_text = getline(v:lnum) + if cur_text =~# '^\s*\%('.g:mp_close_tag.'\)' + return max([a:curr_indent - shiftwidth(), 0]) + endif + return a:curr_indent +endfunction +" }}} + +" Main function {{{ +" +" Note: Every rule of indentation in MetaPost is very subjective. We might get +" creative, but things get murky very soon (there are too many corner cases). +" So, we provide a means for the user to decide what to do when this script +" doesn't get it. We use a simple idea: use '%>', '%<' and '%=' to explicitly +" control indentation. The '<' and '>' symbols may be repeated many times +" (e.g., '%>>' will cause the next line to be indented twice). +" +" By using '%>...', '%<...' and '%=', the indentation the user wants is +" preserved by commands like gg=G, even if it does not follow the rules of +" this script. +" +" Example: +" +" def foo = +" makepen( +" subpath(T-n,t) of r %> +" shifted .5down %> +" --subpath(t,T) of r shifted .5up -- cycle %<<< +" ) +" withcolor black +" enddef +" +" The default indentation of the previous example would be: +" +" def foo = +" makepen( +" subpath(T-n,t) of r +" shifted .5down +" --subpath(t,T) of r shifted .5up -- cycle +" ) +" withcolor black +" enddef +" +" Personally, I prefer the latter, but anyway... +function! GetMetaPostIndentIntern() + " Do not touch indentation inside verbatimtex/btex.. etex blocks. + if synIDattr(synID(v:lnum, 1, 1), "name") =~# '^mpTeXinsert$\|^tex\|^Delimiter' + return -1 + endif + + " This is the reference line relative to which the current line is indented + " (but see below). + let lnum = s:PrevNonBlankNonComment(v:lnum) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let prev_text = getline(lnum) + + " User-defined overrides take precedence over anything else. + " See above for an example. + let j = match(prev_text, '%[<>=]') + if j > 0 + let i = strlen(matchstr(prev_text, '%>\+', j)) - 1 + if i > 0 + return indent(lnum) + i * shiftwidth() + endif + + let i = strlen(matchstr(prev_text, '%<\+', j)) - 1 + if i > 0 + return max([indent(lnum) - i * shiftwidth(), 0]) + endif + + if match(prev_text, '%=', j) + return indent(lnum) + endif + endif + + " If the reference line ends with an open tag, indent. + " + " Example: + " + " if c: + " 0 + " else: + " 1 + " fi if c2: % Note that this line has weight equal to zero. + " ... % This line will be indented + if s:LastTagIsOpen(prev_text) + return s:DecreaseIndentOnClosingTag(indent(lnum) + shiftwidth()) + endif + + " Lines with a positive weight are unbalanced and should likely be indented. + " + " Example: + " + " def f = enddef for i = 1 upto 5: if x[i] > 0: 1 else: 2 fi + " ... % This line will be indented (because of the unterminated `for`) + if s:Weight(prev_text) > 0 + return s:DecreaseIndentOnClosingTag(indent(lnum) + shiftwidth()) + endif + + " Unterminated statements cause indentation to kick in. + " + " Example: + " + " draw unitsquare + " withcolor black; % This line is indented because of `draw`. + " x := a + b + c + " + d + e; % This line is indented because of `:=`. + " + let i = s:LastValidMatchEnd(prev_text, g:mp_statement, 0) + if i >= 0 " Does the line contain a statement? + if s:ValidMatchEnd(prev_text, ';', i) < 0 " Is the statement unterminated? + return indent(lnum) + shiftwidth() + else + return s:DecreaseIndentOnClosingTag(indent(lnum)) + endif + endif + + " Deal with the special case of a statement spanning multiple lines. If the + " current reference line L ends with a semicolon, search backwards for + " another semicolon or a statement keyword. If the latter is found first, + " its line is used as the reference line for indenting the current line + " instead of L. + " + " Example: + " + " if cond: + " draw if a: z0 else: z1 fi + " shifted S + " scaled T; % L + " + " for i = 1 upto 3: % <-- Current line: this gets the same indent as `draw ...` + " + " NOTE: we get here only if L does not contain a statement (among those + " listed in g:mp_statement). + if s:ValidMatchEnd(prev_text, ';'.s:eol, 0) >= 0 " L ends with a semicolon + let stm_lnum = s:PrevNonBlankNonComment(lnum) + while stm_lnum > 0 + let prev_text = getline(stm_lnum) + let sc_pos = s:LastValidMatchEnd(prev_text, ';', 0) + let stm_pos = s:ValidMatchEnd(prev_text, g:mp_statement, sc_pos) + if stm_pos > sc_pos + let lnum = stm_lnum + break + elseif sc_pos > stm_pos + break + endif + let stm_lnum = s:PrevNonBlankNonComment(stm_lnum) + endwhile + endif + + return s:DecreaseIndentOnClosingTag(indent(lnum)) +endfunction +" }}} + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vim:sw=2:fdm=marker + +endif diff --git a/indent/nsis.vim b/indent/nsis.vim new file mode 100644 index 00000000..0ffa1b2e --- /dev/null +++ b/indent/nsis.vim @@ -0,0 +1,95 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nsis') == -1 + +" Vim indent file +" Language: NSIS script +" Maintainer: Ken Takata +" URL: https://github.com/k-takata/vim-nsis +" Last Change: 2018-01-21 +" Filenames: *.nsi +" License: VIM License + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent +setlocal noautoindent +setlocal indentexpr=GetNsisIndent(v:lnum) +setlocal indentkeys=!^F,o,O +setlocal indentkeys+==~${Else,=~${EndIf,=~${EndUnless,=~${AndIf,=~${AndUnless,=~${OrIf,=~${OrUnless,=~${Case,=~${Default,=~${EndSelect,=~${EndSwith,=~${Loop,=~${Next,=~${MementoSectionEnd,=~FunctionEnd,=~SectionEnd,=~SectionGroupEnd,=~PageExEnd,0=~!macroend,0=~!if,0=~!else,0=~!endif + +if exists("*GetNsisIndent") + finish +endif + +function! GetNsisIndent(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) + shiftwidth() * 2 + endif + + " Grab the current line, stripping comments. + let l:thisl = substitute(getline(a:lnum), '[;#].*$', '', '') + " Check if this line is a conditional preprocessor line. + let l:preproc = l:thisl =~? '^\s*!\%(if\|else\|endif\)' + + " Grab the previous line, stripping comments. + " Skip preprocessor lines and continued lines. + let l:prevlnum = a:lnum + while 1 + let l:prevlnum = prevnonblank(l:prevlnum - 1) + if l:prevlnum == 0 + " top of file + return 0 + endif + let l:prevl = substitute(getline(l:prevlnum), '[;#].*$', '', '') + let l:prevpreproc = l:prevl =~? '^\s*!\%(if\|else\|endif\)' + if l:preproc == l:prevpreproc && getline(l:prevlnum - 1) !~? '\\$' + break + endif + endwhile + let l:previ = indent(l:prevlnum) + let l:ind = l:previ + + if l:preproc + " conditional preprocessor + if l:prevl =~? '^\s*!\%(if\%(\%(macro\)\?n\?def\)\?\|else\)\>' + let l:ind += shiftwidth() + endif + if l:thisl =~? '^\s*!\%(else\|endif\)\?\>' + let l:ind -= shiftwidth() + endif + return l:ind + endif + + if l:prevl =~? '^\s*\%(\${\%(If\|IfNot\|Unless\|ElseIf\|ElseIfNot\|ElseUnless\|Else\|AndIf\|AndIfNot\|AndUnless\|OrIf\|OrIfNot\|OrUnless\|Select\|Case\|Case[2-5]\|CaseElse\|Default\|Switch\|Do\|DoWhile\|DoUntil\|For\|ForEach\|MementoSection\)}\|Function\>\|Section\>\|SectionGroup\|PageEx\>\|!macro\>\)' + " previous line opened a block + let l:ind += shiftwidth() + endif + if l:thisl =~? '^\s*\%(\${\%(ElseIf\|ElseIfNot\|ElseUnless\|Else\|EndIf\|EndUnless\|AndIf\|AndIfNot\|AndUnless\|OrIf\|OrIfNot\|OrUnless\|Loop\|LoopWhile\|LoopUntil\|Next\|MementoSectionEnd\)\>}\?\|FunctionEnd\>\|SectionEnd\>\|SectionGroupEnd\|PageExEnd\>\|!macroend\>\)' + " this line closed a block + let l:ind -= shiftwidth() + elseif l:thisl =~? '^\s*\${\%(Case\|Case[2-5]\|CaseElse\|Default\)\>}\?' + if l:prevl !~? '^\s*\${\%(Select\|Switch\)}' + let l:ind -= shiftwidth() + endif + elseif l:thisl =~? '^\s*\${\%(EndSelect\|EndSwitch\)\>}\?' + " this line closed a block + if l:prevl =~? '^\s*\${\%(Select\|Switch\)}' + let l:ind -= shiftwidth() + else + let l:ind -= shiftwidth() * 2 + endif + endif + + return l:ind +endfunction + +" vim: ts=8 sw=2 sts=2 + +endif diff --git a/indent/occam.vim b/indent/occam.vim new file mode 100644 index 00000000..9361bf48 --- /dev/null +++ b/indent/occam.vim @@ -0,0 +1,191 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'occam') == -1 + +" Vim indent file +" Language: occam +" Maintainer: Mario Schweigler <ms44@kent.ac.uk> +" Last Change: 23 April 2003 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +"{{{ Settings +" Set the occam indent function +setlocal indentexpr=GetOccamIndent() +" Indent after new line and after initial colon +setlocal indentkeys=o,O,0=: +"}}} + +" Only define the function once +if exists("*GetOccamIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +"{{{ Indent definitions +" Define carriage return indent +let s:FirstLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\|PAR\|SEQ\|PRI\s\+PAR\|WHILE\|VALOF\|CLAIM\|FORKING\)\>\|\(--.*\)\@<!\(\<PROC\>\|??\|\<CASE\>\s*\(--.*\)\=\_$\)' +let s:FirstLevelNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>' +let s:SecondLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\)\>\|\(--.*\)\@<!?\s*\<CASE\>\s*\(--.*\)\=\_$' +let s:SecondLevelNonColonEndIndent = '\(--.*\)\@<!\<\(CHAN\|DATA\)\s\+TYPE\>' + +" Define colon indent +let s:ColonIndent = '\(--.*\)\@<!\<PROC\>' +let s:ColonNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>' + +let s:ColonEnd = '\(--.*\)\@<!:\s*\(--.*\)\=$' +let s:ColonStart = '^\s*:\s*\(--.*\)\=$' + +" Define comment +let s:CommentLine = '^\s*--' +"}}} + +"{{{ function GetOccamIndent() +" Auxiliary function to get the correct indent for a line of occam code +function GetOccamIndent() + + " Ensure magic is on + let save_magic = &magic + setlocal magic + + " Get reference line number + let linenum = prevnonblank(v:lnum - 1) + while linenum > 0 && getline(linenum) =~ s:CommentLine + let linenum = prevnonblank(linenum - 1) + endwhile + + " Get current indent + let curindent = indent(linenum) + + " Get current line + let line = getline(linenum) + + " Get previous line number + let prevlinenum = prevnonblank(linenum - 1) + while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine + let prevlinenum = prevnonblank(prevlinenum - 1) + endwhile + + " Get previous line + let prevline = getline(prevlinenum) + + " Colon indent + if getline(v:lnum) =~ s:ColonStart + + let found = 0 + + while found < 1 + + if line =~ s:ColonStart + let found = found - 1 + elseif line =~ s:ColonIndent || (line =~ s:ColonNonColonEndIndent && line !~ s:ColonEnd) + let found = found + 1 + endif + + if found < 1 + let linenum = prevnonblank(linenum - 1) + if linenum > 0 + let line = getline(linenum) + else + let found = 1 + endif + endif + + endwhile + + if linenum > 0 + let curindent = indent(linenum) + else + let colonline = getline(v:lnum) + let tabstr = '' + while strlen(tabstr) < &tabstop + let tabstr = ' ' . tabstr + endwhile + let colonline = substitute(colonline, '\t', tabstr, 'g') + let curindent = match(colonline, ':') + endif + + " Restore magic + if !save_magic|setlocal nomagic|endif + + return curindent + endif + + if getline(v:lnum) =~ '^\s*:' + let colonline = getline(v:lnum) + let tabstr = '' + while strlen(tabstr) < &tabstop + let tabstr = ' ' . tabstr + endwhile + let colonline = substitute(colonline, '\t', tabstr, 'g') + let curindent = match(colonline, ':') + + " Restore magic + if !save_magic|setlocal nomagic|endif + + return curindent + endif + + " Carriage return indenat + if line =~ s:FirstLevelIndent || (line =~ s:FirstLevelNonColonEndIndent && line !~ s:ColonEnd) + \ || (line !~ s:ColonStart && (prevline =~ s:SecondLevelIndent + \ || (prevline =~ s:SecondLevelNonColonEndIndent && prevline !~ s:ColonEnd))) + let curindent = curindent + shiftwidth() + + " Restore magic + if !save_magic|setlocal nomagic|endif + + return curindent + endif + + " Commented line + if getline(prevnonblank(v:lnum - 1)) =~ s:CommentLine + + " Restore magic + if !save_magic|setlocal nomagic|endif + + return indent(prevnonblank(v:lnum - 1)) + endif + + " Look for previous second level IF / ALT / PRI ALT + let found = 0 + + while !found + + if indent(prevlinenum) == curindent - shiftwidth() + let found = 1 + endif + + if !found + let prevlinenum = prevnonblank(prevlinenum - 1) + while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine + let prevlinenum = prevnonblank(prevlinenum - 1) + endwhile + if prevlinenum == 0 + let found = 1 + endif + endif + + endwhile + + if prevlinenum > 0 + if getline(prevlinenum) =~ s:SecondLevelIndent + let curindent = curindent + shiftwidth() + endif + endif + + " Restore magic + if !save_magic|setlocal nomagic|endif + + return curindent + +endfunction +"}}} + +let &cpo = s:keepcpo +unlet s:keepcpo + +endif diff --git a/indent/pascal.vim b/indent/pascal.vim new file mode 100644 index 00000000..e112a84e --- /dev/null +++ b/indent/pascal.vim @@ -0,0 +1,232 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pascal') == -1 + +" Vim indent file +" Language: Pascal +" Maintainer: Neil Carter <n.carter@swansea.ac.uk> +" Created: 2004 Jul 13 +" Last Change: 2017 Jun 13 +" +" This is version 2.0, a complete rewrite. +" +" For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/ + + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetPascalIndent(v:lnum) +setlocal indentkeys& +setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for +setlocal indentkeys+==program,==function,==procedure,==object,==private +setlocal indentkeys+==record,==if,==else,==case + +if exists("*GetPascalIndent") + finish +endif + + +function! s:GetPrevNonCommentLineNum( line_num ) + + " Skip lines starting with a comment + let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)' + + let nline = a:line_num + while nline > 0 + let nline = prevnonblank(nline-1) + if getline(nline) !~? SKIP_LINES + break + endif + endwhile + + return nline +endfunction + + +function! s:PurifyCode( line_num ) + " Strip any trailing comments and whitespace + let pureline = 'TODO' + return pureline +endfunction + + +function! GetPascalIndent( line_num ) + + " Line 0 always goes at column 0 + if a:line_num == 0 + return 0 + endif + + let this_codeline = getline( a:line_num ) + + + " SAME INDENT + + " Middle of a three-part comment + if this_codeline =~ '^\s*\*' + return indent( a:line_num - 1) + endif + + + " COLUMN 1 ALWAYS + + " Last line of the program + if this_codeline =~ '^\s*end\.' + return 0 + endif + + " Compiler directives, allowing "(*" and "{" + "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)' + if this_codeline =~ '^\s*\({\|(\*\)\$' + return 0 + endif + + " section headers + if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>' + return 0 + endif + + " Subroutine separators, lines ending with "const" or "var" + if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$' + return 0 + endif + + + " OTHERWISE, WE NEED TO LOOK FURTHER BACK... + + let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num ) + let prev_codeline = getline( prev_codeline_num ) + let indnt = indent( prev_codeline_num ) + + + " INCREASE INDENT + + " If the PREVIOUS LINE ended in these items, always indent + if prev_codeline =~ '\<\(type\|const\|var\)$' + return indnt + shiftwidth() + endif + + if prev_codeline =~ '\<repeat$' + if this_codeline !~ '^\s*until\>' + return indnt + shiftwidth() + else + return indnt + endif + endif + + if prev_codeline =~ '\<\(begin\|record\)$' + if this_codeline !~ '^\s*end\>' + return indnt + shiftwidth() + else + return indnt + endif + endif + + " If the PREVIOUS LINE ended with these items, indent if not + " followed by "begin" + if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$' + if this_codeline !~ '^\s*begin\>' + return indnt + shiftwidth() + else + " If it does start with "begin" then keep the same indent + "return indnt + shiftwidth() + return indnt + endif + endif + + " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers + " only the line before the current one. TODO: Get it working for + " parameter lists longer than two lines. + if prev_codeline =~ '([^)]\+$' + return indnt + shiftwidth() + endif + + + " DECREASE INDENT + + " Lines starting with "else", but not following line ending with + " "end". + if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$' + return indnt - shiftwidth() + endif + + " Lines after a single-statement branch/loop. + " Two lines before ended in "then", "else", or "do" + " Previous line didn't end in "begin" + let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num ) + let prev2_codeline = getline( prev2_codeline_num ) + if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$' + " If the next code line after a single statement branch/loop + " starts with "end", "except" or "finally", we need an + " additional unindentation. + if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$' + " Note that we don't return from here. + return indnt - 2 * shiftwidth() + endif + return indnt - shiftwidth() + endif + + " Lines starting with "until" or "end". This rule must be overridden + " by the one for "end" after a single-statement branch/loop. In + " other words that rule should come before this one. + if this_codeline =~ '^\s*\(end\|until\)\>' + return indnt - shiftwidth() + endif + + + " MISCELLANEOUS THINGS TO CATCH + + " Most "begin"s will have been handled by now. Any remaining + " "begin"s on their own line should go in column 1. + if this_codeline =~ '^\s*begin$' + return 0 + endif + + +" ____________________________________________________________________ +" Object/Borland Pascal/Delphi Extensions +" +" Note that extended-pascal is handled here, unless it is simpler to +" handle them in the standard-pascal section above. + + + " COLUMN 1 ALWAYS + + " section headers at start of line. + if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>' + return 0 + endif + + + " INDENT ONCE + + " If the PREVIOUS LINE ended in these items, always indent. + if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$' + return indnt + shiftwidth() + endif + + " ???? Indent "procedure" and "functions" if they appear within an + " class/object definition. But that means overriding standard-pascal + " rule where these words always go in column 1. + + + " UNINDENT ONCE + + if this_codeline =~ '^\s*\(except\|finally\)$' + return indnt - shiftwidth() + endif + + if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$' + return indnt - shiftwidth() + endif + + +" ____________________________________________________________________ + + " If nothing changed, return same indent. + return indnt +endfunction + + +endif diff --git a/indent/postscr.vim b/indent/postscr.vim new file mode 100644 index 00000000..04e91cc4 --- /dev/null +++ b/indent/postscr.vim @@ -0,0 +1,72 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'postscr') == -1 + +" PostScript indent file +" Language: PostScript +" Maintainer: Mike Williams <mrw@netcomuk.co.uk> +" Last Change: 2nd July 2001 +" + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=PostscrIndentGet(v:lnum) +setlocal indentkeys+=0],0=>>,0=%%,0=end,0=restore,0=grestore indentkeys-=:,0#,e + +" Catch multiple instantiations +if exists("*PostscrIndentGet") + finish +endif + +function! PostscrIndentGet(lnum) + " Find a non-empty non-comment line above the current line. + " Note: ignores DSC comments as well! + let lnum = a:lnum - 1 + while lnum != 0 + let lnum = prevnonblank(lnum) + if getline(lnum) !~ '^\s*%.*$' + break + endif + let lnum = lnum - 1 + endwhile + + " Hit the start of the file, use user indent. + if lnum == 0 + return -1 + endif + + " Start with the indent of the previous line + let ind = indent(lnum) + let pline = getline(lnum) + + " Indent for dicts, arrays, and saves with possible trailing comment + if pline =~ '\(begin\|<<\|g\=save\|{\|[\)\s*\(%.*\)\=$' + let ind = ind + shiftwidth() + endif + + " Remove indent for popped dicts, and restores. + if pline =~ '\(end\|g\=restore\)\s*$' + let ind = ind - shiftwidth() + + " Else handle immediate dedents of dicts, restores, and arrays. + elseif getline(a:lnum) =~ '\(end\|>>\|g\=restore\|}\|]\)' + let ind = ind - shiftwidth() + + " Else handle DSC comments - always start of line. + elseif getline(a:lnum) =~ '^\s*%%' + let ind = 0 + endif + + " For now catch excessive left indents if they occur. + if ind < 0 + let ind = -1 + endif + + return ind +endfunction + +" vim:sw=2 + +endif diff --git a/indent/pov.vim b/indent/pov.vim new file mode 100644 index 00000000..dca8d2e1 --- /dev/null +++ b/indent/pov.vim @@ -0,0 +1,88 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pov') == -1 + +" Vim indent file +" Language: PoV-Ray Scene Description Language +" Maintainer: David Necas (Yeti) <yeti@physics.muni.cz> +" Last Change: 2017 Jun 13 +" URI: http://trific.ath.cx/Ftp/vim/indent/pov.vim + +" 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 indentexpr=GetPoVRayIndent() +setlocal indentkeys+==else,=end,0] + +" Only define the function once. +if exists("*GetPoVRayIndent") + finish +endif + +" Counts matches of a regexp <rexp> in line number <line>. +" Doesn't count matches inside strings and comments (as defined by current +" syntax). +function! s:MatchCount(line, rexp) + let str = getline(a:line) + let i = 0 + let n = 0 + while i >= 0 + let i = matchend(str, a:rexp, i) + if i >= 0 && synIDattr(synID(a:line, i, 0), "name") !~? "string\|comment" + let n = n + 1 + endif + endwhile + return n +endfunction + +" The main function. Returns indent amount. +function GetPoVRayIndent() + " If we are inside a comment (may be nested in obscure ways), give up + if synIDattr(synID(v:lnum, indent(v:lnum)+1, 0), "name") =~? "string\|comment" + return -1 + endif + + " Search backwards for the frist non-empty, non-comment line. + let plnum = prevnonblank(v:lnum - 1) + let plind = indent(plnum) + while plnum > 0 && synIDattr(synID(plnum, plind+1, 0), "name") =~? "comment" + let plnum = prevnonblank(plnum - 1) + let plind = indent(plnum) + endwhile + + " Start indenting from zero + if plnum == 0 + return 0 + endif + + " Analyse previous nonempty line. + let chg = 0 + let chg = chg + s:MatchCount(plnum, '[[{(]') + let chg = chg + s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\|while\|macro\|else\)\>') + let chg = chg - s:MatchCount(plnum, '#\s*end\>') + let chg = chg - s:MatchCount(plnum, '[]})]') + " Dirty hack for people writing #if and #else on the same line. + let chg = chg - s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\)\>.*#\s*else\>') + " When chg > 0, then we opened groups and we should indent more, but when + " chg < 0, we closed groups and this already affected the previous line, + " so we should not dedent. And when everything else fails, scream. + let chg = chg > 0 ? chg : 0 + + " Analyse current line + " FIXME: If we have to dedent, we should try to find the indentation of the + " opening line. + let cur = s:MatchCount(v:lnum, '^\s*\%(#\s*\%(end\|else\)\>\|[]})]\)') + if cur > 0 + let final = plind + (chg - cur) * shiftwidth() + else + let final = plind + chg * shiftwidth() + endif + + return final < 0 ? 0 : final +endfunction + +endif diff --git a/indent/pyrex.vim b/indent/pyrex.vim new file mode 100644 index 00000000..c4662c31 --- /dev/null +++ b/indent/pyrex.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'pyrex') == -1 + +" Vim indent file +" Language: Pyrex +" Maintainer: Marco Barisione <marco.bari@people.it> +" URL: http://marcobari.altervista.org/pyrex_vim.html +" Last Change: 2005 Jun 24 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" Use Python formatting rules +runtime! indent/python.vim + +endif diff --git a/indent/readline.vim b/indent/readline.vim new file mode 100644 index 00000000..5c83059d --- /dev/null +++ b/indent/readline.vim @@ -0,0 +1,40 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'readline') == -1 + +" Vim indent file +" Language: readline configuration file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetReadlineIndent() +setlocal indentkeys=!^F,o,O,=$else,=$endif +setlocal nosmartindent + +if exists("*GetReadlineIndent") + finish +endif + +function GetReadlineIndent() + let lnum = prevnonblank(v:lnum - 1) + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + + if getline(lnum) =~ '^\s*$\(if\|else\)\>' + let ind = ind + shiftwidth() + endif + + if getline(v:lnum) =~ '^\s*$\(else\|endif\)\>' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/rmd.vim b/indent/rmd.vim new file mode 100644 index 00000000..25ec7023 --- /dev/null +++ b/indent/rmd.vim @@ -0,0 +1,70 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rmd') == -1 + +" Vim indent file +" Language: Rmd +" Author: Jakson Alves de Aquino <jalvesaq@gmail.com> +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Sun Aug 19, 2018 09:14PM + + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +runtime indent/r.vim +let s:RIndent = function(substitute(&indentexpr, "()", "", "")) +let b:did_indent = 1 + +setlocal indentkeys=0{,0},:,!^F,o,O,e +setlocal indentexpr=GetRmdIndent() + +if exists("*GetRmdIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function s:GetMdIndent() + let pline = getline(v:lnum - 1) + let cline = getline(v:lnum) + if prevnonblank(v:lnum - 1) < v:lnum - 1 || cline =~ '^\s*[-\+\*]\s' || cline =~ '^\s*\d\+\.\s\+' + return indent(v:lnum) + elseif pline =~ '^\s*[-\+\*]\s' + return indent(v:lnum - 1) + 2 + elseif pline =~ '^\s*\d\+\.\s\+' + return indent(v:lnum - 1) + 3 + endif + return indent(prevnonblank(v:lnum - 1)) +endfunction + +function s:GetYamlIndent() + let pline = getline(v:lnum - 1) + if pline =~ ':\s*$' + return indent(v:lnum) + shiftwidth() + elseif pline =~ '^\s*- ' + return indent(v:lnum) + 2 + endif + return indent(prevnonblank(v:lnum - 1)) +endfunction + +function GetRmdIndent() + if getline(".") =~ '^[ \t]*```{r .*}$' || getline(".") =~ '^[ \t]*```$' + return 0 + endif + if search('^[ \t]*```{r', "bncW") > search('^[ \t]*```$', "bncW") + return s:RIndent() + elseif v:lnum > 1 && search('^---$', "bnW") == 1 && + \ (search('^---$', "nW") > v:lnum || search('^...$', "nW") > v:lnum) + return s:GetYamlIndent() + else + return s:GetMdIndent() + endif +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: sw=2 + +endif diff --git a/indent/rnoweb.vim b/indent/rnoweb.vim new file mode 100644 index 00000000..0abe0128 --- /dev/null +++ b/indent/rnoweb.vim @@ -0,0 +1,51 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rnoweb') == -1 + +" Vim indent file +" Language: Rnoweb +" Author: Jakson Alves de Aquino <jalvesaq@gmail.com> +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Fri Apr 15, 2016 10:58PM + + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +runtime indent/tex.vim + +function! s:NoTeXIndent() + return indent(line(".")) +endfunction + +if &indentexpr == "" || &indentexpr == "GetRnowebIndent()" + let s:TeXIndent = function("s:NoTeXIndent") +else + let s:TeXIndent = function(substitute(&indentexpr, "()", "", "")) +endif + +unlet! b:did_indent +runtime indent/r.vim +let s:RIndent = function(substitute(&indentexpr, "()", "", "")) +let b:did_indent = 1 + +setlocal indentkeys=0{,0},!^F,o,O,e,},=\bibitem,=\item +setlocal indentexpr=GetRnowebIndent() + +if exists("*GetRnowebIndent") + finish +endif + +function GetRnowebIndent() + let curline = getline(".") + if curline =~ '^<<.*>>=$' || curline =~ '^\s*@$' + return 0 + endif + if search("^<<", "bncW") > search("^@", "bncW") + return s:RIndent() + endif + return s:TeXIndent() +endfunction + +" vim: sw=2 + +endif diff --git a/indent/rpl.vim b/indent/rpl.vim new file mode 100644 index 00000000..190a8335 --- /dev/null +++ b/indent/rpl.vim @@ -0,0 +1,67 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rpl') == -1 + +" Vim indent file +" Language: RPL/2 +" Version: 0.2 +" Last Change: 2017 Jun 13 +" Maintainer: BERTRAND Joël <rpl2@free.fr> + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentkeys+==~end,=~case,=~if,=~then,=~else,=~do,=~until,=~while,=~repeat,=~select,=~default,=~for,=~start,=~next,=~step,<<>,<>> + +" Define the appropriate indent function but only once +setlocal indentexpr=RplGetFreeIndent() +if exists("*RplGetFreeIndent") + finish +endif + +let b:undo_indent = "set ai< indentkeys< indentexpr<" + +function RplGetIndent(lnum) + let ind = indent(a:lnum) + let prevline=getline(a:lnum) + " Strip tail comment + let prevstat=substitute(prevline, '!.*$', '', '') + + " Add a shiftwidth to statements following if, iferr, then, else, elseif, + " case, select, default, do, until, while, repeat, for, start + if prevstat =~? '\<\(if\|iferr\|do\|while\)\>' && prevstat =~? '\<end\>' + elseif prevstat =~? '\(^\|\s\+\)<<\($\|\s\+\)' && prevstat =~? '\s\+>>\($\|\s\+\)' + elseif prevstat =~? '\<\(if\|iferr\|then\|else\|elseif\|select\|case\|do\|until\|while\|repeat\|for\|start\|default\)\>' || prevstat =~? '\(^\|\s\+\)<<\($\|\s\+\)' + let ind = ind + shiftwidth() + endif + + " Subtract a shiftwidth from then, else, elseif, end, until, repeat, next, + " step + let line = getline(v:lnum) + if line =~? '^\s*\(then\|else\|elseif\|until\|repeat\|next\|step\|default\|end\)\>' + let ind = ind - shiftwidth() + elseif line =~? '^\s*>>\($\|\s\+\)' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +function RplGetFreeIndent() + " Find the previous non-blank line + let lnum = prevnonblank(v:lnum - 1) + + " Use zero indent at the top of the file + if lnum == 0 + return 0 + endif + + let ind=RplGetIndent(lnum) + return ind +endfunction + +" vim:sw=2 tw=130 + +endif diff --git a/indent/rrst.vim b/indent/rrst.vim new file mode 100644 index 00000000..9d346ce2 --- /dev/null +++ b/indent/rrst.vim @@ -0,0 +1,51 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rrst') == -1 + +" Vim indent file +" Language: Rrst +" Author: Jakson Alves de Aquino <jalvesaq@gmail.com> +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Tue Apr 07, 2015 04:38PM + + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +runtime indent/r.vim +let s:RIndent = function(substitute(&indentexpr, "()", "", "")) +let b:did_indent = 1 + +setlocal indentkeys=0{,0},:,!^F,o,O,e +setlocal indentexpr=GetRrstIndent() + +if exists("*GetRrstIndent") + finish +endif + +function GetRstIndent() + let pline = getline(v:lnum - 1) + let cline = getline(v:lnum) + if prevnonblank(v:lnum - 1) < v:lnum - 1 || cline =~ '^\s*[-\+\*]\s' || cline =~ '^\s*\d\+\.\s\+' + return indent(v:lnum) + elseif pline =~ '^\s*[-\+\*]\s' + return indent(v:lnum - 1) + 2 + elseif pline =~ '^\s*\d\+\.\s\+' + return indent(v:lnum - 1) + 3 + endif + return indent(prevnonblank(v:lnum - 1)) +endfunction + +function GetRrstIndent() + if getline(".") =~ '^\.\. {r .*}$' || getline(".") =~ '^\.\. \.\.$' + return 0 + endif + if search('^\.\. {r', "bncW") > search('^\.\. \.\.$', "bncW") + return s:RIndent() + else + return GetRstIndent() + endif +endfunction + +" vim: sw=2 + +endif diff --git a/indent/sas.vim b/indent/sas.vim new file mode 100644 index 00000000..8fad4690 --- /dev/null +++ b/indent/sas.vim @@ -0,0 +1,142 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'sas') == -1 + +" Vim indent file +" Language: SAS +" Maintainer: Zhen-Huan Hu <wildkeny@gmail.com> +" Version: 3.0.3 +" Last Change: Jun 26, 2018 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetSASIndent() +setlocal indentkeys+=;,=~data,=~proc,=~macro + +if exists("*GetSASIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" Regex that captures the start of a data/proc section +let s:section_str = '\v%(^|;)\s*%(data|proc)>' +" Regex that captures the end of a run-processing section +let s:section_run = '\v%(^|;)\s*run\s*;' +" Regex that captures the end of a data/proc section +let s:section_end = '\v%(^|;)\s*%(quit|enddata)\s*;' + +" Regex that captures the start of a control block (anything inside a section) +let s:block_str = '\v<%(do>%([^;]+<%(to|over|while)>[^;]+)=|%(compute|define\s+%(column|footer|header|style|table|tagset|crosstabs|statgraph)|edit|layout|method|select)>[^;]+|begingraph)\s*;' +" Regex that captures the end of a control block (anything inside a section) +let s:block_end = '\v<%(end|endcomp|endlayout|endgraph)\s*;' + +" Regex that captures the start of a macro +let s:macro_str = '\v%(^|;)\s*\%macro>' +" Regex that captures the end of a macro +let s:macro_end = '\v%(^|;)\s*\%mend\s*;' + +" Regex that defines the end of the program +let s:program_end = '\v%(^|;)\s*endsas\s*;' + +" List of procs supporting run-processing +let s:run_processing_procs = [ + \ 'catalog', 'chart', 'datasets', 'document', 'ds2', 'plot', 'sql', + \ 'gareabar', 'gbarline', 'gchart', 'gkpi', 'gmap', 'gplot', 'gradar', 'greplay', 'gslide', 'gtile', + \ 'anova', 'arima', 'catmod', 'factex', 'glm', 'model', 'optex', 'plan', 'reg', + \ 'iml', + \ ] + +" Find the line number of previous keyword defined by the regex +function! s:PrevMatch(lnum, regex) + let prev_lnum = prevnonblank(a:lnum - 1) + while prev_lnum > 0 + let prev_line = getline(prev_lnum) + if prev_line =~? a:regex + break + else + let prev_lnum = prevnonblank(prev_lnum - 1) + endif + endwhile + return prev_lnum +endfunction + +" Main function +function! GetSASIndent() + let prev_lnum = prevnonblank(v:lnum - 1) + if prev_lnum ==# 0 + " Leave the indentation of the first line unchanged + return indent(1) + else + let prev_line = getline(prev_lnum) + " Previous non-blank line contains the start of a macro/section/block + " while not the end of a macro/section/block (at the same line) + if (prev_line =~? s:section_str && prev_line !~? s:section_run && prev_line !~? s:section_end) || + \ (prev_line =~? s:block_str && prev_line !~? s:block_end) || + \ (prev_line =~? s:macro_str && prev_line !~? s:macro_end) + let ind = indent(prev_lnum) + shiftwidth() + elseif prev_line =~? s:section_run && prev_line !~? s:section_end + let prev_section_str_lnum = s:PrevMatch(v:lnum, s:section_str) + let prev_section_end_lnum = max([ + \ s:PrevMatch(v:lnum, s:section_end), + \ s:PrevMatch(v:lnum, s:macro_end ), + \ s:PrevMatch(v:lnum, s:program_end)]) + " Check if the section supports run-processing + if prev_section_end_lnum < prev_section_str_lnum && + \ getline(prev_section_str_lnum) =~? '\v%(^|;)\s*proc\s+%(' . + \ join(s:run_processing_procs, '|') . ')>' + let ind = indent(prev_lnum) + shiftwidth() + else + let ind = indent(prev_lnum) + endif + else + let ind = indent(prev_lnum) + endif + endif + " Re-adjustments based on the inputs of the current line + let curr_line = getline(v:lnum) + if curr_line =~? s:program_end + " End of the program + " Same indentation as the first non-blank line + return indent(nextnonblank(1)) + elseif curr_line =~? s:macro_end + " Current line is the end of a macro + " Match the indentation of the start of the macro + return indent(s:PrevMatch(v:lnum, s:macro_str)) + elseif curr_line =~? s:block_end && curr_line !~? s:block_str + " Re-adjust if current line is the end of a block + " while not the beginning of a block (at the same line) + " Returning the indent of previous block start directly + " would not work due to nesting + let ind = ind - shiftwidth() + elseif curr_line =~? s:section_str || curr_line =~? s:section_run || curr_line =~? s:section_end + " Re-adjust if current line is the start/end of a section + " since the end of a section could be inexplicit + let prev_section_str_lnum = s:PrevMatch(v:lnum, s:section_str) + " Check if the previous section supports run-processing + if getline(prev_section_str_lnum) =~? '\v%(^|;)\s*proc\s+%(' . + \ join(s:run_processing_procs, '|') . ')>' + let prev_section_end_lnum = max([ + \ s:PrevMatch(v:lnum, s:section_end), + \ s:PrevMatch(v:lnum, s:macro_end ), + \ s:PrevMatch(v:lnum, s:program_end)]) + else + let prev_section_end_lnum = max([ + \ s:PrevMatch(v:lnum, s:section_end), + \ s:PrevMatch(v:lnum, s:section_run), + \ s:PrevMatch(v:lnum, s:macro_end ), + \ s:PrevMatch(v:lnum, s:program_end)]) + endif + if prev_section_end_lnum < prev_section_str_lnum + let ind = ind - shiftwidth() + endif + endif + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/sass.vim b/indent/sass.vim new file mode 100644 index 00000000..f0169e42 --- /dev/null +++ b/indent/sass.vim @@ -0,0 +1,42 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'sass') == -1 + +" Vim indent file +" Language: Sass +" Maintainer: Tim Pope <vimNOSPAM@tpope.org> +" Last Change: 2017 Jun 13 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent sw=2 et +setlocal indentexpr=GetSassIndent() +setlocal indentkeys=o,O,*<Return>,<:>,!^F + +" Only define the function once. +if exists("*GetSassIndent") + finish +endif + +let s:property = '^\s*:\|^\s*[[:alnum:]#{}-]\+\%(:\|\s*=\)' +let s:extend = '^\s*\%(@extend\|@include\|+\)' + +function! GetSassIndent() + let lnum = prevnonblank(v:lnum-1) + let line = substitute(getline(lnum),'\s\+$','','') + let cline = substitute(substitute(getline(v:lnum),'\s\+$','',''),'^\s\+','','') + let lastcol = strlen(line) + let line = substitute(line,'^\s\+','','') + let indent = indent(lnum) + let cindent = indent(v:lnum) + if line !~ s:property && line !~ s:extend && cline =~ s:property + return indent + shiftwidth() + else + return -1 + endif +endfunction + +" vim:set sw=2: + +endif diff --git a/indent/scheme.vim b/indent/scheme.vim new file mode 100644 index 00000000..8faac9b8 --- /dev/null +++ b/indent/scheme.vim @@ -0,0 +1,18 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'scheme') == -1 + +" Vim indent file +" Language: Scheme +" Last Change: 2018 Jan 31 +" Maintainer: Evan Hanson <evhan@foldling.org> +" Previous Maintainer: Sergey Khorev <sergey.khorev@gmail.com> +" URL: https://foldling.org/vim/indent/scheme.vim + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" Use the Lisp indenting +runtime! indent/lisp.vim + +endif diff --git a/indent/sdl.vim b/indent/sdl.vim new file mode 100644 index 00000000..10d494dc --- /dev/null +++ b/indent/sdl.vim @@ -0,0 +1,97 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'sdl') == -1 + +" Vim indent file +" Language: SDL +" Maintainer: Michael Piefel <entwurf@piefel.de> +" Last Change: 10 December 2011 + +" Shamelessly stolen from the Vim-Script indent file + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetSDLIndent() +setlocal indentkeys+==~end,=~state,*<Return> + +" Only define the function once. +if exists("*GetSDLIndent") +" finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function! GetSDLIndent() + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + let virtuality = '^\s*\(\(virtual\|redefined\|finalized\)\s\+\)\=\s*' + + " Add a single space to comments which use asterisks + if getline(lnum) =~ '^\s*\*' + let ind = ind - 1 + endif + if getline(v:lnum) =~ '^\s*\*' + let ind = ind + 1 + endif + + " Add a 'shiftwidth' after states, different blocks, decision (and alternatives), inputs + if (getline(lnum) =~? '^\s*\(start\|state\|system\|package\|connection\|channel\|alternative\|macro\|operator\|newtype\|select\|substructure\|decision\|generator\|refinement\|service\|method\|exceptionhandler\|asntype\|syntype\|value\|(.*):\|\(priority\s\+\)\=input\|provided\)' + \ || getline(lnum) =~? virtuality . '\(process\|procedure\|block\|object\)') + \ && getline(lnum) !~? 'end[[:alpha:]]\+;$' + let ind = ind + shiftwidth() + endif + + " Subtract a 'shiftwidth' after states + if getline(lnum) =~? '^\s*\(stop\|return\>\|nextstate\)' + let ind = ind - shiftwidth() + endif + + " Subtract a 'shiftwidth' on on end (uncompleted line) + if getline(v:lnum) =~? '^\s*end\>' + let ind = ind - shiftwidth() + endif + + " Put each alternatives where the corresponding decision was + if getline(v:lnum) =~? '^\s*\((.*)\|else\):' + normal k + let ind = indent(searchpair('^\s*decision', '', '^\s*enddecision', 'bW', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "sdlString"')) + endif + + " Put each state where the preceding state was + if getline(v:lnum) =~? '^\s*state\>' + let ind = indent(search('^\s*start', 'bW')) + endif + + " Systems and packages are always in column 0 + if getline(v:lnum) =~? '^\s*\(\(end\)\=system\|\(end\)\=package\)' + return 0 + endif + + " Put each end* where the corresponding begin was + if getline(v:lnum) =~? '^\s*end[[:alpha:]]' + normal k + let partner=matchstr(getline(v:lnum), '\(' . virtuality . 'end\)\@<=[[:alpha:]]\+') + let ind = indent(searchpair(virtuality . partner, '', '^\s*end' . partner, 'bW', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "sdlString"')) + endif + + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:sw=2 + +endif diff --git a/indent/sml.vim b/indent/sml.vim new file mode 100644 index 00000000..13b35a86 --- /dev/null +++ b/indent/sml.vim @@ -0,0 +1,221 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'sml') == -1 + +" Vim indent file +" Language: SML +" Maintainer: Saikat Guha <sg266@cornell.edu> +" Hubert Chao <hc85@cornell.edu> +" Original OCaml Version: +" Jean-Francois Yuen <jfyuen@ifrance.com> +" Mike Leary <leary@nwlink.com> +" Markus Mottl <markus@oefai.at> +" OCaml URL: http://www.oefai.at/~markus/vim/indent/ocaml.vim +" Last Change: 2003 Jan 04 - Adapted to SML +" 2002 Nov 06 - Some fixes (JY) +" 2002 Oct 28 - Fixed bug with indentation of ']' (MM) +" 2002 Oct 22 - Major rewrite (JY) + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal expandtab +setlocal indentexpr=GetSMLIndent() +setlocal indentkeys+=0=and,0=else,0=end,0=handle,0=if,0=in,0=let,0=then,0=val,0=fun,0=\|,0=*),0) +setlocal nolisp +setlocal nosmartindent +setlocal textwidth=80 +setlocal shiftwidth=2 + +" Comment formatting +if (has("comments")) + set comments=sr:(*,mb:*,ex:*) + set fo=cqort +endif + +" Only define the function once. +"if exists("*GetSMLIndent") +"finish +"endif + +" Define some patterns: +let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|;\)\s*$' +let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>' +let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$' +let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>' +let s:module = '\<\%(let\|sig\|struct\)\>' +let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$' +let s:type = '^\s*\%(let\|type\)\>.*=' +let s:val = '^\s*\(val\|external\)\>.*:' + +" Skipping pattern, for comments +function! s:SkipPattern(lnum, pat) + let def = prevnonblank(a:lnum - 1) + while def > 0 && getline(def) =~ a:pat + let def = prevnonblank(def - 1) + endwhile + return def +endfunction + +" Indent for ';;' to match multiple 'let' +function! s:GetInd(lnum, pat, lim) + let llet = search(a:pat, 'bW') + let old = indent(a:lnum) + while llet > 0 + let old = indent(llet) + let nb = s:SkipPattern(llet, '^\s*(\*.*\*)\s*$') + if getline(nb) =~ a:lim + return old + endif + let llet = search(a:pat, 'bW') + endwhile + return old +endfunction + +" Indent pairs +function! s:FindPair(pstart, pmid, pend) + call search(a:pend, 'bW') +" return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) + let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"') + if lno == -1 + return indent(lno) + else + return col(".") - 1 + endif +endfunction + +function! s:FindLet(pstart, pmid, pend) + call search(a:pend, 'bW') +" return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) + let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"') + let moduleLine = getline(lno) + if lno == -1 || moduleLine =~ '^\s*\(fun\|structure\|signature\)\>' + return indent(lno) + else + return col(".") - 1 + endif +endfunction + +" Indent 'let' +"function! s:FindLet(pstart, pmid, pend) +" call search(a:pend, 'bW') +" return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ "^\\s*let\\>.*=\\s*$\\|" . s:beflet')) +"endfunction + +function! GetSMLIndent() + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + let lline = getline(lnum) + + " Return double 'shiftwidth' after lines matching: + if lline =~ '^\s*|.*=>\s*$' + return ind + 2 *shiftwidth() + elseif lline =~ '^\s*val\>.*=\s*$' + return ind + shiftwidth() + endif + + let line = getline(v:lnum) + + " Indent lines starting with 'end' to matching module + if line =~ '^\s*end\>' + return s:FindLet(s:module, '', '\<end\>') + + " Match 'else' with 'if' + elseif line =~ '^\s*else\>' + if lline !~ '^\s*\(if\|else\|then\)\>' + return s:FindPair('\<if\>', '', '\<then\>') + else + return ind + endif + + " Match 'then' with 'if' + elseif line =~ '^\s*then\>' + if lline !~ '^\s*\(if\|else\|then\)\>' + return s:FindPair('\<if\>', '', '\<then\>') + else + return ind + endif + + " Indent if current line begins with ']' + elseif line =~ '^\s*\]' + return s:FindPair('\[','','\]') + + " Indent current line starting with 'in' to last matching 'let' + elseif line =~ '^\s*in\>' + let ind = s:FindLet('\<let\>','','\<in\>') + + " Indent from last matching module if line matches: + elseif line =~ '^\s*\(fun\|val\|open\|structure\|and\|datatype\|type\|exception\)\>' + cursor(lnum,1) + let lastModule = indent(searchpair(s:module, '', '\<end\>', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) + if lastModule == -1 + return 0 + else + return lastModule + shiftwidth() + endif + + " Indent lines starting with '|' from matching 'case', 'handle' + elseif line =~ '^\s*|' + " cursor(lnum,1) + let lastSwitch = search('\<\(case\|handle\|fun\|datatype\)\>','bW') + let switchLine = getline(lastSwitch) + let switchLineIndent = indent(lastSwitch) + if lline =~ '^\s*|' + return ind + endif + if switchLine =~ '\<case\>' + return col(".") + 2 + elseif switchLine =~ '\<handle\>' + return switchLineIndent + shiftwidth() + elseif switchLine =~ '\<datatype\>' + call search('=') + return col(".") - 1 + else + return switchLineIndent + 2 + endif + + + " Indent if last line ends with 'sig', 'struct', 'let', 'then', 'else', + " 'in' + elseif lline =~ '\<\(sig\|struct\|let\|in\|then\|else\)\s*$' + let ind = ind + shiftwidth() + + " Indent if last line ends with 'of', align from 'case' + elseif lline =~ '\<\(of\)\s*$' + call search('\<case\>',"bW") + let ind = col(".")+4 + + " Indent if current line starts with 'of' + elseif line =~ '^\s*of\>' + call search('\<case\>',"bW") + let ind = col(".")+1 + + + " Indent if last line starts with 'fun', 'case', 'fn' + elseif lline =~ '^\s*\(fun\|fn\|case\)\>' + let ind = ind + shiftwidth() + + endif + + " Don't indent 'let' if last line started with 'fun', 'fn' + if line =~ '^\s*let\>' + if lline =~ '^\s*\(fun\|fn\)' + let ind = ind - shiftwidth() + endif + endif + + return ind + +endfunction + +" vim:sw=2 + +endif diff --git a/indent/sshconfig.vim b/indent/sshconfig.vim new file mode 100644 index 00000000..c25e297d --- /dev/null +++ b/indent/sshconfig.vim @@ -0,0 +1,38 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'sshconfig') == -1 + +" Vim indent file +" Language: ssh config file +" Maintainer: JasonKim <git@jasonk.me> +" Last Change: 2020 May 16 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetSshconfigIndent(v:lnum) +setlocal indentkeys=o,O,*<Return>,0=~host\ ,0=~match\ ,0#,!^F + +let b:undo_indent = "setlocal autoindent< indentexpr< indentkeys<" + +if exists("*GetSshconfigIndent") + finish +endif + +function GetSshconfigIndent(lnum) + let sw = shiftwidth() + let prev_lnum = prevnonblank(a:lnum - 1) + let curr_lnum = a:lnum + let prev_line = getline(prev_lnum) + let curr_line = getline(curr_lnum) + if curr_line =~? '^\s*\(host\|match\)\s' + return 0 + elseif prev_line =~? '^\s*\(host\|match\)\s' + return sw + else + return indent(prev_lnum) + endif +endfunction + +endif diff --git a/indent/systemverilog.vim b/indent/systemverilog.vim new file mode 100644 index 00000000..82b27794 --- /dev/null +++ b/indent/systemverilog.vim @@ -0,0 +1,233 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'systemverilog') == -1 + +" Vim indent file +" Language: SystemVerilog +" Maintainer: kocha <kocha.lsifrontend@gmail.com> +" Last Change: 05-Feb-2017 by Bilal Wasim + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=SystemVerilogIndent() +setlocal indentkeys=!^F,o,O,0),0},=begin,=end,=join,=endcase,=join_any,=join_none +setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify +setlocal indentkeys+==endclass,=endpackage,=endsequence,=endclocking +setlocal indentkeys+==endinterface,=endgroup,=endprogram,=endproperty,=endchecker +setlocal indentkeys+==`else,=`endif + +" Only define the function once. +if exists("*SystemVerilogIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function SystemVerilogIndent() + + if exists('b:systemverilog_indent_width') + let offset = b:systemverilog_indent_width + else + let offset = shiftwidth() + endif + if exists('b:systemverilog_indent_modules') + let indent_modules = offset + else + let indent_modules = 0 + endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let lnum2 = prevnonblank(lnum - 1) + let curr_line = getline(v:lnum) + let last_line = getline(lnum) + let last_line2 = getline(lnum2) + let ind = indent(lnum) + let ind2 = indent(lnum - 1) + let offset_comment1 = 1 + " Define the condition of an open statement + " Exclude the match of //, /* or */ + let sv_openstat = '\(\<or\>\|\([*/]\)\@<![*(,{><+-/%^&|!=?:]\([*/]\)\@!\)' + " Define the condition when the statement ends with a one-line comment + let sv_comment = '\(//.*\|/\*.*\*/\s*\)' + if exists('b:verilog_indent_verbose') + let vverb_str = 'INDENT VERBOSE:' + let vverb = 1 + else + let vverb = 0 + endif + + " Indent accoding to last line + " End of multiple-line comment + if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/' + let ind = ind - offset_comment1 + if vverb + echo vverb_str "De-indent after a multiple-line comment." + endif + + " Indent after if/else/for/case/always/initial/specify/fork blocks + elseif last_line =~ '`\@<!\<\(if\|else\)\>' || + \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\|do\|foreach\|forever\|randcase\)\>' || + \ last_line =~ '^\s*\<\(always\|always_comb\|always_ff\|always_latch\)\>' || + \ last_line =~ '^\s*\<\(initial\|specify\|fork\|final\)\>' + if last_line !~ '\(;\|\<end\>\)\s*' . sv_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after a block statement." | endif + endif + " Indent after function/task/class/package/sequence/clocking/ + " interface/covergroup/property/checkerprogram blocks + elseif last_line =~ '^\s*\<\(function\|task\|class\|package\)\>' || + \ last_line =~ '^\s*\<\(sequence\|clocking\|interface\)\>' || + \ last_line =~ '^\s*\(\w\+\s*:\)\=\s*\<covergroup\>' || + \ last_line =~ '^\s*\<\(property\|checker\|program\)\>' + if last_line !~ '\<end\>\s*' . sv_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after function/task/class block statement." + endif + endif + + " Indent after module/function/task/specify/fork blocks + elseif last_line =~ '^\s*\(\<extern\>\s*\)\=\<module\>' + let ind = ind + indent_modules + if vverb && indent_modules + echo vverb_str "Indent after module statement." + endif + if last_line =~ '[(,]\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*[(,]\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a multiple-line module statement." + endif + endif + + " Indent after a 'begin' statement + elseif last_line =~ '\(\<begin\>\)\(\s*:\s*\w\+\)*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\(\<begin\>\)' && + \ ( last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . sv_comment . '*$' ) + let ind = ind + offset + if vverb | echo vverb_str "Indent after begin statement." | endif + + " Indent after a '{' or a '(' + elseif last_line =~ '[{(]' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*[{(]' && + \ ( last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . sv_comment . '*$' ) + let ind = ind + offset + if vverb | echo vverb_str "Indent after begin statement." | endif + + " De-indent for the end of one-line block + elseif ( last_line !~ '\<begin\>' || + \ last_line =~ '\(//\|/\*\).*\<begin\>' ) && + \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|forever\|final\)\>.*' . + \ sv_comment . '*$' && + \ last_line2 !~ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|forever\|final\)\>' && + \ last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' && + \ ( last_line2 !~ '\<begin\>' || + \ last_line2 =~ '\(//\|/\*\).*\<begin\>' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent after the end of one-line statement." + endif + + " Multiple-line statement (including case statement) + " Open statement + " Ident the first open line + elseif last_line =~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*' . sv_openstat . '\s*$' && + \ last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after an open statement." | endif + + " Close statement + " De-indent for an optional close parenthesis and a semicolon, and only + " if there exists precedent non-whitespace char + elseif last_line =~ ')*\s*;\s*' . sv_comment . '*$' && + \ last_line !~ '^\s*)*\s*;\s*' . sv_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . sv_comment . '*$' && + \ ( last_line2 =~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line2 !~ ';\s*//.*$') && + \ last_line2 !~ '^\s*' . sv_comment . '$' + let ind = ind - offset + if vverb | echo vverb_str "De-indent after a close statement." | endif + + " `ifdef and `else + elseif last_line =~ '^\s*`\<\(ifdef\|else\)\>' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a `ifdef or `else statement." + endif + + endif + + " Re-indent current line + + " De-indent on the end of the block + " join/end/endcase/endfunction/endtask/endspecify + if curr_line =~ '^\s*\<\(join\|join_any\|join_none\|\|end\|endcase\|while\)\>' || + \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\|endclass\)\>' || + \ curr_line =~ '^\s*\<\(endpackage\|endsequence\|endclocking\|endinterface\)\>' || + \ curr_line =~ '^\s*\<\(endgroup\|endproperty\|endchecker\|endprogram\)\>' || + \ curr_line =~ '^\s*}' + let ind = ind - offset + if vverb | echo vverb_str "De-indent the end of a block." | endif + elseif curr_line =~ '^\s*\<endmodule\>' + let ind = ind - indent_modules + if vverb && indent_modules + echo vverb_str "De-indent the end of a module." + endif + + " De-indent on a stand-alone 'begin' + elseif curr_line =~ '^\s*\<begin\>' + if last_line !~ '^\s*\<\(function\|task\|specify\|module\|class\|package\)\>' || + \ last_line !~ '^\s*\<\(sequence\|clocking\|interface\|covergroup\)\>' || + \ last_line !~ '^\s*\<\(property\|checker\|program\)\>' && + \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . sv_comment . '*$' && + \ ( last_line =~ + \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\|do\|foreach\|forever\|randcase\|final\)\>' || + \ last_line =~ ')\s*' . sv_comment . '*$' || + \ last_line =~ sv_openstat . '\s*' . sv_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent a stand alone begin statement." + endif + endif + + " De-indent after the end of multiple-line statement + elseif curr_line =~ '^\s*)' && + \ ( last_line =~ sv_openstat . '\s*' . sv_comment . '*$' || + \ last_line !~ sv_openstat . '\s*' . sv_comment . '*$' && + \ last_line2 =~ sv_openstat . '\s*' . sv_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent the end of a multiple statement." + endif + + " De-indent `else and `endif + elseif curr_line =~ '^\s*`\<\(else\|endif\)\>' + let ind = ind - offset + if vverb | echo vverb_str "De-indent `else and `endif statement." | endif + + endif + + " Return the indention + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:sw=2 +endif diff --git a/indent/tcl.vim b/indent/tcl.vim new file mode 100644 index 00000000..3ad7b4e1 --- /dev/null +++ b/indent/tcl.vim @@ -0,0 +1,105 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'tcl') == -1 + +" Vim indent file +" Language: Tcl +" Latest Update: Chris Heithoff <chrisheithoff@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2018-12-05 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetTclIndent() +setlocal indentkeys=0{,0},!^F,o,O,0] +setlocal nosmartindent + +if exists("*GetTclIndent") + finish +endif + +function s:prevnonblanknoncomment(lnum) + let lnum = prevnonblank(a:lnum) + while lnum > 0 + let line = getline(lnum) + if line !~ '^\s*\(#\|$\)' + break + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return lnum +endfunction + +function s:ends_with_backslash(lnum) + let line = getline(a:lnum) + if line =~ '\\\s*$' + return 1 + else + return 0 + endif +endfunction + +function s:count_braces(lnum, count_open) + let n_open = 0 + let n_close = 0 + let line = getline(a:lnum) + let pattern = '[{}]' + let i = match(line, pattern) + while i != -1 + if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'tcl\%(Comment\|String\)' + if line[i] == '{' + let n_open += 1 + elseif line[i] == '}' + if n_open > 0 + let n_open -= 1 + else + let n_close += 1 + endif + endif + endif + let i = match(line, pattern, i + 1) + endwhile + return a:count_open ? n_open : n_close +endfunction + +function GetTclIndent() + let line = getline(v:lnum) + + " Get the line number of the previous non-blank or non-comment line. + let pnum = s:prevnonblanknoncomment(v:lnum - 1) + if pnum == 0 + return 0 + endif + + " ..and the previous line before the previous line. + let pnum2 = s:prevnonblanknoncomment(pnum-1) + + " Default indentation is to preserve the previous indentation. + let ind = indent(pnum) + + " ...but if previous line introduces an open brace, then increase current line's indentation + if s:count_braces(pnum, 1) > 0 + let ind += shiftwidth() + else + " Look for backslash line continuation on the previous two lines. + let slash1 = s:ends_with_backslash(pnum) + let slash2 = s:ends_with_backslash(pnum2) + if slash1 && !slash2 + " If the previous line begins a line continuation. + let ind += shiftwidth() + elseif !slash1 && slash2 + " If two lines ago was the end of a line continuation group of lines. + let ind -= shiftwidth() + endif + endif + + " If the current line begins with a closed brace, then decrease the indentation by one. + if line =~ '^\s*}' + let ind -= shiftwidth() + endif + + return ind +endfunction + +endif diff --git a/indent/teraterm.vim b/indent/teraterm.vim new file mode 100644 index 00000000..cde67689 --- /dev/null +++ b/indent/teraterm.vim @@ -0,0 +1,59 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'teraterm') == -1 + +" Vim indent file +" Language: Tera Term Language (TTL) +" Based on Tera Term Version 4.100 +" Maintainer: Ken Takata +" URL: https://github.com/k-takata/vim-teraterm +" Last Change: 2018-08-31 +" Filenames: *.ttl +" License: VIM License + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent +setlocal noautoindent +setlocal indentexpr=GetTeraTermIndent(v:lnum) +setlocal indentkeys=!^F,o,O,e +setlocal indentkeys+==elseif,=endif,=loop,=next,=enduntil,=endwhile + +if exists("*GetTeraTermIndent") + finish +endif + +function! GetTeraTermIndent(lnum) + let l:prevlnum = prevnonblank(a:lnum-1) + if l:prevlnum == 0 + " top of file + return 0 + endif + + " grab the previous and current line, stripping comments. + let l:prevl = substitute(getline(l:prevlnum), ';.*$', '', '') + let l:thisl = substitute(getline(a:lnum), ';.*$', '', '') + let l:previ = indent(l:prevlnum) + + let l:ind = l:previ + + if l:prevl =~ '^\s*if\>.*\<then\>' + " previous line opened a block + let l:ind += shiftwidth() + endif + if l:prevl =~ '^\s*\%(elseif\|else\|do\|until\|while\|for\)\>' + " previous line opened a block + let l:ind += shiftwidth() + endif + if l:thisl =~ '^\s*\%(elseif\|else\|endif\|enduntil\|endwhile\|loop\|next\)\>' + " this line closed a block + let l:ind -= shiftwidth() + endif + + return l:ind +endfunction + +" vim: ts=8 sw=2 sts=2 + +endif diff --git a/indent/tex.vim b/indent/tex.vim new file mode 100644 index 00000000..54c45307 --- /dev/null +++ b/indent/tex.vim @@ -0,0 +1,427 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'tex') == -1 + +" Vim indent file +" Language: LaTeX +" Maintainer: Yichao Zhou <broken.zhou AT gmail.com> +" Created: Sat, 16 Feb 2002 16:50:19 +0100 +" Version: 1.0.0 +" Please email me if you found something I can do. Comments, bug report and +" feature request are welcome. + +" Last Update: {{{ +" 25th Sep 2002, by LH : +" (*) better support for the option +" (*) use some regex instead of several '||'. +" Oct 9th, 2003, by JT: +" (*) don't change indentation of lines starting with '%' +" 2005/06/15, Moshe Kaminsky <kaminsky AT math.huji.ac.il> +" (*) New variables: +" g:tex_items, g:tex_itemize_env, g:tex_noindent_env +" 2011/3/6, by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Don't change indentation of lines starting with '%' +" I don't see any code with '%' and it doesn't work properly +" so I add some code. +" (*) New features: Add smartindent-like indent for "{}" and "[]". +" (*) New variables: g:tex_indent_brace +" 2011/9/25, by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Bug fix: smartindent-like indent for "[]" +" (*) New features: Align with "&". +" (*) New variable: g:tex_indent_and. +" 2011/10/23 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Bug fix: improve the smartindent-like indent for "{}" and +" "[]". +" 2012/02/27 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Bug fix: support default folding marker. +" (*) Indent with "&" is not very handy. Make it not enable by +" default. +" 2012/03/06 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Modify "&" behavior and make it default again. Now "&" +" won't align when there are more then one "&" in the previous +" line. +" (*) Add indent "\left(" and "\right)" +" (*) Trust user when in "verbatim" and "lstlisting" +" 2012/03/11 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Modify "&" so that only indent when current line start with +" "&". +" 2012/03/12 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Modify indentkeys. +" 2012/03/18 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Add &cpo +" 2013/05/02 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Fix problem about GetTeXIndent checker. Thank Albert Netymk +" for reporting this. +" 2014/06/23 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Remove the feature g:tex_indent_and because it is buggy. +" (*) If there is not any obvious indentation hints, we do not +" alert our user's current indentation. +" (*) g:tex_indent_brace now only works if the open brace is the +" last character of that line. +" 2014/08/03 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Indent current line if last line has larger indentation +" 2016/11/08 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Fix problems for \[ and \]. Thanks Bruno for reporting. +" 2017/04/30 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Fix a bug between g:tex_noindent_env and g:tex_indent_items +" Now g:tex_noindent_env='document\|verbatim\|itemize' (Emacs +" style) is supported. Thanks Miles Wheeler for reporting. +" 2018/02/07 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Make indentation more smart in the normal mode +" 2020/04/26 by Yichao Zhou <broken.zhou AT gmail.com> +" (*) Fix a bug related to \[ & \]. Thanks Manuel Boni for +" reporting. +" +" }}} + +" Document: {{{ +" +" For proper latex experience, please put +" let g:tex_flavor = "latex" +" into your vimrc. +" +" * g:tex_indent_brace +" +" If this variable is unset or non-zero, it will use smartindent-like style +" for "{}" and "[]". Now this only works if the open brace is the last +" character of that line. +" +" % Example 1 +" \usetikzlibrary{ +" external +" } +" +" % Example 2 +" \tikzexternalize[ +" prefix=tikz] +" +" * g:tex_indent_items +" +" If this variable is set, item-environments are indented like Emacs does +" it, i.e., continuation lines are indented with a shiftwidth. +" +" set unset +" ------------------------------------------------------ +" \begin{itemize} \begin{itemize} +" \item blablabla \item blablabla +" bla bla bla bla bla bla +" \item blablabla \item blablabla +" bla bla bla bla bla bla +" \end{itemize} \end{itemize} +" +" +" * g:tex_items +" +" A list of tokens to be considered as commands for the beginning of an item +" command. The tokens should be separated with '\|'. The initial '\' should +" be escaped. The default is '\\bibitem\|\\item'. +" +" * g:tex_itemize_env +" +" A list of environment names, separated with '\|', where the items (item +" commands matching g:tex_items) may appear. The default is +" 'itemize\|description\|enumerate\|thebibliography'. +" +" * g:tex_noindent_env +" +" A list of environment names. separated with '\|', where no indentation is +" required. The default is 'document\|verbatim'. +" }}} + +" Only define the function once +if exists("b:did_indent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" Define global variable {{{ + +let b:did_indent = 1 + +if !exists("g:tex_indent_items") + let g:tex_indent_items = 1 +endif +if !exists("g:tex_indent_brace") + let g:tex_indent_brace = 1 +endif +if !exists("g:tex_max_scan_line") + let g:tex_max_scan_line = 60 +endif +if g:tex_indent_items + if !exists("g:tex_itemize_env") + let g:tex_itemize_env = 'itemize\|description\|enumerate\|thebibliography' + endif + if !exists('g:tex_items') + let g:tex_items = '\\bibitem\|\\item' + endif +else + let g:tex_items = '' +endif + +if !exists("g:tex_noindent_env") + let g:tex_noindent_env = 'document\|verbatim\|lstlisting' +endif "}}} + +" VIM Setting " {{{ +setlocal autoindent +setlocal nosmartindent +setlocal indentexpr=GetTeXIndent() +setlocal indentkeys& +exec 'setlocal indentkeys+=[,(,{,),},],\&' . substitute(g:tex_items, '^\|\(\\|\)', ',=', 'g') +let g:tex_items = '^\s*' . substitute(g:tex_items, '^\(\^\\s\*\)*', '', '') +" }}} + +function! GetTeXIndent() " {{{ + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + let cnum = v:lnum + + " Comment line is not what we need. + while lnum != 0 && getline(lnum) =~ '^\s*%' + let lnum = prevnonblank(lnum - 1) + endwhile + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let line = substitute(getline(lnum), '\s*%.*', '','g') " last line + let cline = substitute(getline(v:lnum), '\s*%.*', '', 'g') " current line + + let ccol = 1 + while cline[ccol] =~ '\s' + let ccol += 1 + endwhile + + " We are in verbatim, so do what our user what. + if synIDattr(synID(v:lnum, ccol, 1), "name") == "texZone" + if empty(cline) + return indent(lnum) + else + return indent(v:lnum) + endif + endif + + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + let stay = 1 + + " New code for comment: retain the indent of current line + if cline =~ '^\s*%' + return indent(v:lnum) + endif + + " Add a 'shiftwidth' after beginning of environments. + " Don't add it for \begin{document} and \begin{verbatim} + " if line =~ '^\s*\\begin{\(.*\)}' && line !~ 'verbatim' + " LH modification : \begin does not always start a line + " ZYC modification : \end after \begin won't cause wrong indent anymore + if line =~ '\\begin{.*}' + if line !~ g:tex_noindent_env + let ind = ind + shiftwidth() + let stay = 0 + endif + + if g:tex_indent_items + " Add another sw for item-environments + if line =~ g:tex_itemize_env + let ind = ind + shiftwidth() + let stay = 0 + endif + endif + endif + + if cline =~ '\\end{.*}' + let retn = s:GetEndIndentation(v:lnum) + if retn != -1 + return retn + endif + end + " Subtract a 'shiftwidth' when an environment ends + if cline =~ '\\end{.*}' + \ && cline !~ g:tex_noindent_env + \ && cline !~ '\\begin{.*}.*\\end{.*}' + if g:tex_indent_items + " Remove another sw for item-environments + if cline =~ g:tex_itemize_env + let ind = ind - shiftwidth() + let stay = 0 + endif + endif + + let ind = ind - shiftwidth() + let stay = 0 + endif + + if g:tex_indent_brace + if line =~ '[[{]$' + let ind += shiftwidth() + let stay = 0 + endif + + if cline =~ '^\s*\\\?[\]}]' && s:CheckPairedIsLastCharacter(v:lnum, ccol) + let ind -= shiftwidth() + let stay = 0 + endif + + if line !~ '^\s*\\\?[\]}]' + for i in range(1, strlen(line)-1) + let char = line[i] + if char == ']' || char == '}' + if s:CheckPairedIsLastCharacter(lnum, i) + let ind -= shiftwidth() + let stay = 0 + endif + endif + endfor + endif + endif + + " Special treatment for 'item' + " ---------------------------- + + if g:tex_indent_items + " '\item' or '\bibitem' itself: + if cline =~ g:tex_items + let ind = ind - shiftwidth() + let stay = 0 + endif + " lines following to '\item' are intented once again: + if line =~ g:tex_items + let ind = ind + shiftwidth() + let stay = 0 + endif + endif + + if stay && mode() == 'i' + " If there is no obvious indentation hint, and indentation is triggered + " in insert mode, we trust our user. + if empty(cline) + return ind + else + return max([indent(v:lnum), s:GetLastBeginIndentation(v:lnum)]) + endif + else + return ind + endif +endfunction "}}} + +function! s:GetLastBeginIndentation(lnum) " {{{ + let matchend = 1 + for lnum in range(a:lnum-1, max([a:lnum - g:tex_max_scan_line, 1]), -1) + let line = getline(lnum) + if line =~ '\\end{.*}' + let matchend += 1 + endif + if line =~ '\\begin{.*}' + let matchend -= 1 + endif + if matchend == 0 + if line =~ g:tex_noindent_env + return indent(lnum) + endif + if line =~ g:tex_itemize_env + return indent(lnum) + 2 * shiftwidth() + endif + return indent(lnum) + shiftwidth() + endif + endfor + return -1 +endfunction + +function! s:GetEndIndentation(lnum) " {{{ + if getline(a:lnum) =~ '\\begin{.*}.*\\end{.*}' + return -1 + endif + + let min_indent = 100 + let matchend = 1 + for lnum in range(a:lnum-1, max([a:lnum-g:tex_max_scan_line, 1]), -1) + let line = getline(lnum) + if line =~ '\\end{.*}' + let matchend += 1 + endif + if line =~ '\\begin{.*}' + let matchend -= 1 + endif + if matchend == 0 + return indent(lnum) + endif + if !empty(line) + let min_indent = min([min_indent, indent(lnum)]) + endif + endfor + return min_indent - shiftwidth() +endfunction + +" Most of the code is from matchparen.vim +function! s:CheckPairedIsLastCharacter(lnum, col) "{{{ + let c_lnum = a:lnum + let c_col = a:col+1 + + let line = getline(c_lnum) + if line[c_col-1] == '\' + let c_col = c_col + 1 + endif + let c = line[c_col-1] + + let plist = split(&matchpairs, '.\zs[:,]') + let i = index(plist, c) + if i < 0 + return 0 + endif + + " Figure out the arguments for searchpairpos(). + if i % 2 == 0 + let s_flags = 'nW' + let c2 = plist[i + 1] + else + let s_flags = 'nbW' + let c2 = c + let c = plist[i - 1] + endif + if c == '[' + let c = '\[' + let c2 = '\]' + endif + + " Find the match. When it was just before the cursor move it there for a + " moment. + let save_cursor = winsaveview() + call cursor(c_lnum, c_col) + + " When not in a string or comment ignore matches inside them. + " We match "escape" for special items, such as lispEscapeSpecial. + let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . + \ '=~? "string\\|character\\|singlequote\\|escape\\|comment"' + execute 'if' s_skip '| let s_skip = 0 | endif' + + let stopline = max([0, c_lnum - g:tex_max_scan_line]) + + " Limit the search time to 300 msec to avoid a hang on very long lines. + " This fails when a timeout is not supported. + try + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 100) + catch /E118/ + endtry + + call winrestview(save_cursor) + + if m_lnum > 0 + let line = getline(m_lnum) + return strlen(line) == m_col + endif + + return 0 +endfunction "}}} + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: set sw=4 textwidth=80: + +endif diff --git a/indent/tf.vim b/indent/tf.vim new file mode 100644 index 00000000..ba22883c --- /dev/null +++ b/indent/tf.vim @@ -0,0 +1,76 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'tf') == -1 + +" Vim indent file +" Language: tf (TinyFugue) +" Maintainer: Christian J. Robinson <heptite@gmail.com> +" URL: http://www.vim.org/scripts/script.php?script_id=174 +" Last Change: 2017 Feb 25 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetTFIndent() +setlocal indentkeys-=0{,0} indentkeys-=0# indentkeys-=: +setlocal indentkeys+==/endif,=/then,=/else,=/done,0; + +" Only define the function once: +if exists("*GetTFIndent") + finish +endif + +function GetTFIndent() + " Find a non-blank line above the current line: + let lnum = prevnonblank(v:lnum - 1) + + " No indent for the start of the file: + if lnum == 0 + return 0 + endif + + let ind = indent(lnum) + let line = getline(lnum) + + " No indentation if the previous line didn't end with "\": + " (Could be annoying, but it lets you know if you made a mistake.) + if line !~ '\\$' + return 0 + endif + + if line =~ '\(/def.*\\\|/for.*\(%;\s*\)\@\<!\\\)$' + let ind = ind + shiftwidth() + elseif line =~ '\(/if\|/else\|/then\)' + if line !~ '/endif' + let ind = ind + shiftwidth() + endif + elseif line =~ '/while' + if line !~ '/done' + let ind = ind + shiftwidth() + endif + endif + + let line = getline(v:lnum) + + if line =~ '\(/else\|/endif\|/then\)' + if line !~ '/if' + let ind = ind - shiftwidth() + endif + elseif line =~ '/done' + if line !~ '/while' + let ind = ind - shiftwidth() + endif + endif + + " Comments at the beginning of a line: + if line =~ '^\s*;' + let ind = 0 + endif + + + return ind + +endfunction + +endif diff --git a/indent/tilde.vim b/indent/tilde.vim new file mode 100644 index 00000000..e23c9806 --- /dev/null +++ b/indent/tilde.vim @@ -0,0 +1,40 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'tilde') == -1 + +"Description: Indent scheme for the tilde weblanguage +"Author: Tobias Rundström <tobi@tobi.nu> +"URL: http://tilde.tildesoftware.net +"Last Change: May 8 09:15:09 CEST 2002 + +if exists ("b:did_indent") + finish +endif + +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetTildeIndent(v:lnum) +setlocal indentkeys=o,O,) + +if exists("*GetTildeIndent") + finish +endif + +function GetTildeIndent(lnum) + let plnum = prevnonblank(v:lnum-1) + + if plnum == 0 + return 0 + endif + + if getline(v:lnum) =~ '^\s*\~\(endif\|else\|elseif\|end\)\>' + return indent(v:lnum) - shiftwidth() + endif + + if getline(plnum) =~ '^\s*\~\(if\|foreach\|foreach_row\|xml_loop\|file_loop\|file_write\|file_append\|imap_loopsections\|imap_index\|imap_list\|ldap_search\|post_loopall\|post_loop\|file_loop\|sql_loop_num\|sql_dbmsselect\|search\|sql_loop\|post\|for\|function_define\|silent\|while\|setvalbig\|mail_create\|systempipe\|mail_send\|dual\|elseif\|else\)\>' + return indent(plnum) + shiftwidth() + else + return -1 + endif +endfunction + +endif diff --git a/indent/treetop.vim b/indent/treetop.vim new file mode 100644 index 00000000..13cb3e44 --- /dev/null +++ b/indent/treetop.vim @@ -0,0 +1,42 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'treetop') == -1 + +" Vim indent file +" Language: Treetop +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2011-03-14 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetTreetopIndent() +setlocal indentkeys=0{,0},!^F,o,O,=end +setlocal nosmartindent + +if exists("*GetTreetopIndent") + finish +endif + +function GetTreetopIndent() + let pnum = prevnonblank(v:lnum - 1) + if pnum == 0 + return 0 + endif + + let ind = indent(pnum) + let line = getline(pnum) + + if line =~ '^\s*\%(grammar\|module\|rule\)\>' + let ind += shiftwidth() + endif + + let line = getline(v:lnum) + if line =~ '^\s*end\>' + let ind -= shiftwidth() + end + + retur ind +endfunction + +endif diff --git a/indent/verilog.vim b/indent/verilog.vim new file mode 100644 index 00000000..43213a8d --- /dev/null +++ b/indent/verilog.vim @@ -0,0 +1,233 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'verilog') == -1 + +" Language: Verilog HDL +" Maintainer: Chih-Tsun Huang <cthuang@cs.nthu.edu.tw> +" Last Change: 2017 Aug 25 by Chih-Tsun Huang +" URL: http://www.cs.nthu.edu.tw/~cthuang/vim/indent/verilog.vim +" +" Credits: +" Suggestions for improvement, bug reports by +" Takuya Fujiwara <tyru.exe@gmail.com> +" Thilo Six <debian@Xk2c.de> +" Leo Butlero <lbutler@brocade.com> +" +" Buffer Variables: +" b:verilog_indent_modules : indenting after the declaration +" of module blocks +" b:verilog_indent_width : indenting width +" b:verilog_indent_verbose : verbose to each indenting +" + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetVerilogIndent() +setlocal indentkeys=!^F,o,O,0),=begin,=end,=join,=endcase +setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify +setlocal indentkeys+==endconfig,=endgenerate,=endprimitive,=endtable +setlocal indentkeys+==`else,=`elsif,=`endif + +" Only define the function once. +if exists("*GetVerilogIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function GetVerilogIndent() + + if exists('b:verilog_indent_width') + let offset = b:verilog_indent_width + else + let offset = shiftwidth() + endif + if exists('b:verilog_indent_modules') + let indent_modules = offset + else + let indent_modules = 0 + endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let lnum2 = prevnonblank(lnum - 1) + let curr_line = getline(v:lnum) + let last_line = getline(lnum) + let last_line2 = getline(lnum2) + let ind = indent(lnum) + let ind2 = indent(lnum - 1) + let offset_comment1 = 1 + " Define the condition of an open statement + " Exclude the match of //, /* or */ + let vlog_openstat = '\(\<or\>\|\([*/]\)\@<![*(,{><+-/%^&|!=?:]\([*/]\)\@!\)' + " Define the condition when the statement ends with a one-line comment + let vlog_comment = '\(//.*\|/\*.*\*/\s*\)' + if exists('b:verilog_indent_verbose') + let vverb_str = 'INDENT VERBOSE:' + let vverb = 1 + else + let vverb = 0 + endif + + " Indent accoding to last line + " End of multiple-line comment + if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/' + let ind = ind - offset_comment1 + if vverb + echo vverb_str "De-indent after a multiple-line comment." + endif + + " Indent after if/else/for/case/always/initial/specify/fork blocks + " Note: We exclude '`if' or '`else' and consider 'end else' + " 'end if' is redundant here + elseif last_line =~ '^\s*\(end\)\=\s*`\@<!\<\(if\|else\)\>' || + \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\)\>' || + \ last_line =~ '^\s*\<\(always\|initial\)\>' || + \ last_line =~ '^\s*\<\(specify\|fork\)\>' + if last_line !~ '\(;\|\<end\>\)\s*' . vlog_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after a block statement." | endif + endif + " Indent after function/task/config/generate/primitive/table blocks + elseif last_line =~ '^\s*\<\(function\|task\|config\|generate\|primitive\|table\)\>' + if last_line !~ '\<end\>\s*' . vlog_comment . '*$' || + \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after function/task block statement." + endif + endif + + " Indent after module/function/task/specify/fork blocks + elseif last_line =~ '^\s*\<module\>' + let ind = ind + indent_modules + if vverb && indent_modules + echo vverb_str "Indent after module statement." + endif + if last_line =~ '[(,]\s*' . vlog_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*[(,]\s*' . vlog_comment . '*$' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a multiple-line module statement." + endif + endif + + " Indent after a 'begin' statement + elseif last_line =~ '\(\<begin\>\)\(\s*:\s*\w\+\)*' . vlog_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\(\<begin\>\)' && + \ ( last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' || + \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . vlog_comment . '*$' ) + let ind = ind + offset + if vverb | echo vverb_str "Indent after begin statement." | endif + + " De-indent for the end of one-line block + elseif ( last_line !~ '\<begin\>' || + \ last_line =~ '\(//\|/\*\).*\<begin\>' ) && + \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>.*' . + \ vlog_comment . '*$' && + \ last_line2 !~ + \ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>' && + \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' && + \ ( last_line2 !~ '\<begin\>' || + \ last_line2 =~ '\(//\|/\*\).*\<begin\>' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent after the end of one-line statement." + endif + + " Multiple-line statement (including case statement) + " Open statement + " Ident the first open line + elseif last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*' . vlog_openstat . '\s*$' && + \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' + let ind = ind + offset + if vverb | echo vverb_str "Indent after an open statement." | endif + + " Close statement + " De-indent for an optional close parenthesis and a semicolon, and only + " if there exists precedent non-whitespace char + elseif last_line =~ ')*\s*;\s*' . vlog_comment . '*$' && + \ last_line !~ '^\s*)*\s*;\s*' . vlog_comment . '*$' && + \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . vlog_comment . '*$' && + \ ( last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' && + \ last_line2 !~ ';\s*//.*$') && + \ last_line2 !~ '^\s*' . vlog_comment . '$' + let ind = ind - offset + if vverb | echo vverb_str "De-indent after a close statement." | endif + + " `ifdef or `ifndef or `elsif or `else + elseif last_line =~ '^\s*`\<\(ifn\?def\|elsif\|else\)\>' + let ind = ind + offset + if vverb + echo vverb_str "Indent after a `ifdef or `ifndef or `elsif or `else statement." + endif + + endif + + " Re-indent current line + + " De-indent on the end of the block + " join/end/endcase/endfunction/endtask/endspecify + if curr_line =~ '^\s*\<\(join\|end\|endcase\)\>' || + \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\)\>' || + \ curr_line =~ '^\s*\<\(endconfig\|endgenerate\|endprimitive\|endtable\)\>' + let ind = ind - offset + if vverb | echo vverb_str "De-indent the end of a block." | endif + elseif curr_line =~ '^\s*\<endmodule\>' + let ind = ind - indent_modules + if vverb && indent_modules + echo vverb_str "De-indent the end of a module." + endif + + " De-indent on a stand-alone 'begin' + elseif curr_line =~ '^\s*\<begin\>' + if last_line !~ '^\s*\<\(function\|task\|specify\|module\|config\|generate\|primitive\|table\)\>' && + \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . vlog_comment . '*$' && + \ ( last_line =~ + \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\)\>' || + \ last_line =~ ')\s*' . vlog_comment . '*$' || + \ last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent a stand alone begin statement." + endif + endif + + " De-indent after the end of multiple-line statement + elseif curr_line =~ '^\s*)' && + \ ( last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' || + \ last_line !~ vlog_openstat . '\s*' . vlog_comment . '*$' && + \ last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' ) + let ind = ind - offset + if vverb + echo vverb_str "De-indent the end of a multiple statement." + endif + + " De-indent `elsif or `else or `endif + elseif curr_line =~ '^\s*`\<\(elsif\|else\|endif\)\>' + let ind = ind - offset + if vverb | echo vverb_str "De-indent `elsif or `else or `endif statement." | endif + + endif + + " Return the indention + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:sw=2 + +endif diff --git a/indent/vhdl.vim b/indent/vhdl.vim new file mode 100644 index 00000000..5e9bfd4e --- /dev/null +++ b/indent/vhdl.vim @@ -0,0 +1,439 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vhdl') == -1 + +" VHDL indent ('93 syntax) +" Language: VHDL +" Maintainer: Gerald Lai <laigera+vim?gmail.com> +" Version: 1.62 +" Last Change: 2017 Oct 17 +" URL: http://www.vim.org/scripts/script.php?script_id=1450 + +" only load this indent file when no other was loaded +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" setup indent options for local VHDL buffer +setlocal indentexpr=GetVHDLindent() +setlocal indentkeys=!^F,o,O,0(,0) +setlocal indentkeys+==~begin,=~end\ ,=~end\ ,=~is,=~select,=~when +setlocal indentkeys+==~if,=~then,=~elsif,=~else +setlocal indentkeys+==~case,=~loop,=~for,=~generate,=~record,=~units,=~process,=~block,=~function,=~component,=~procedure +setlocal indentkeys+==~architecture,=~configuration,=~entity,=~package + +" constants +" not a comment +let s:NC = '\%(--.*\)\@<!' +" end of string +let s:ES = '\s*\%(--.*\)\=$' +" no "end" keyword in front +let s:NE = '\%(\<end\s\+\)\@<!' + +" option to disable alignment of generic/port mappings +if !exists("g:vhdl_indent_genportmap") + let g:vhdl_indent_genportmap = 1 +endif + +" option to disable alignment of right-hand side assignment "<=" statements +if !exists("g:vhdl_indent_rhsassign") + let g:vhdl_indent_rhsassign = 1 +endif + +" only define indent function once +if exists("*GetVHDLindent") + finish +endif + +function GetVHDLindent() + " store current line & string + let curn = v:lnum + let curs = getline(curn) + + " find previous line that is not a comment + let prevn = prevnonblank(curn - 1) + let prevs = getline(prevn) + while prevn > 0 && prevs =~ '^\s*--' + let prevn = prevnonblank(prevn - 1) + let prevs = getline(prevn) + endwhile + let prevs_noi = substitute(prevs, '^\s*', '', '') + + " default indent starts as previous non-comment line's indent + let ind = prevn > 0 ? indent(prevn) : 0 + " backup default + let ind2 = ind + + " indent: special; kill string so it would not affect other filters + " keywords: "report" + string + " where: anywhere in current or previous line + let s0 = s:NC.'\<report\>\s*".*"' + if curs =~? s0 + let curs = "" + endif + if prevs =~? s0 + let prevs = "" + endif + + " indent: previous line's comment position, otherwise follow next non-comment line if possible + " keyword: "--" + " where: start of current line + if curs =~ '^\s*--' + let pn = curn - 1 + let ps = getline(pn) + if curs =~ '^\s*--\s' && ps =~ '--' + return indent(pn) + stridx(substitute(ps, '^\s*', '', ''), '--') + else + " find nextnonblank line that is not a comment + let nn = nextnonblank(curn + 1) + let ns = getline(nn) + while nn > 0 && ns =~ '^\s*--' + let nn = nextnonblank(nn + 1) + let ns = getline(nn) + endwhile + let n = indent(nn) + return n != -1 ? n : ind + endif + endif + + " **************************************************************************************** + " indent: align generic variables & port names + " keywords: "procedure" + name, "generic", "map", "port" + "(", provided current line is part of mapping + " where: anywhere in previous 2 lines + " find following previous non-comment line + let pn = prevnonblank(prevn - 1) + let ps = getline(pn) + while pn > 0 && ps =~ '^\s*--' + let pn = prevnonblank(pn - 1) + let ps = getline(pn) + endwhile + if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*\((.*)\)*\s*\%(=>\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\s\+\)\)') && (prevs =~? s:NC.'\<\%(procedure\s\+\S\+\|generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) + " align closing ")" with opening "(" + if curs =~ '^\s*)' + return ind2 + stridx(prevs_noi, '(') + endif + let m = matchend(prevs_noi, '(\s*\ze\w') + if m != -1 + return ind2 + m + else + if g:vhdl_indent_genportmap + return ind2 + stridx(prevs_noi, '(') + shiftwidth() + else + return ind2 + shiftwidth() + endif + endif + endif + + " indent: align conditional/select statement + " keywords: variable + "<=" without ";" ending + " where: start of previous line + if prevs =~? '^\s*\S\+\s*<=[^;]*'.s:ES + if g:vhdl_indent_rhsassign + return ind2 + matchend(prevs_noi, '<=\s*\ze.') + else + return ind2 + shiftwidth() + endif + endif + + " indent: backtrace previous non-comment lines for next smaller or equal size indent + " keywords: "end" + "record", "units" + " where: start of previous line + " keyword: ")" + " where: start of previous line + " keyword: without "<=" + ";" ending + " where: anywhere in previous line + " keyword: "=>" + ")" ending, provided current line does not begin with ")" + " where: anywhere in previous line + " _note_: indent allowed to leave this filter + let m = 0 + if prevs =~? '^\s*end\s\+\%(record\|units\)\>' + let m = 3 + elseif prevs =~ '^\s*)' + let m = 1 + elseif prevs =~ s:NC.'\%(<=.*\)\@<!;'.s:ES || (curs !~ '^\s*)' && prevs =~ s:NC.'=>.*'.s:NC.')'.s:ES) + let m = 2 + endif + + if m > 0 + let pn = prevnonblank(prevn - 1) + let ps = getline(pn) + while pn > 0 + let t = indent(pn) + if ps !~ '^\s*--' && (t < ind || (t == ind && m == 3)) + " make sure one of these is true + " keywords: variable + "<=" without ";" ending + " where: start of previous non-comment line + " keywords: "procedure", "generic", "map", "port" + " where: anywhere in previous non-comment line + " keyword: "(" + " where: start of previous non-comment line + if m < 3 && ps !~? '^\s*\S\+\s*<=[^;]*'.s:ES + if ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)\>' || ps =~ '^\s*(' + let ind = t + endif + break + endif + let ind = t + if m > 1 + " find following previous non-comment line + let ppn = prevnonblank(pn - 1) + let pps = getline(ppn) + while ppn > 0 && pps =~ '^\s*--' + let ppn = prevnonblank(ppn - 1) + let pps = getline(ppn) + endwhile + " indent: follow + " keyword: "select" + " where: end of following previous non-comment line + " keyword: "type" + " where: start of following previous non-comment line + if m == 2 + let s1 = s:NC.'\<select'.s:ES + if ps !~? s1 && pps =~? s1 + let ind = indent(ppn) + endif + elseif m == 3 + let s1 = '^\s*type\>' + if ps !~? s1 && pps =~? s1 + let ind = indent(ppn) + endif + endif + endif + break + endif + let pn = prevnonblank(pn - 1) + let ps = getline(pn) + endwhile + endif + + " indent: follow indent of previous opening statement, otherwise -sw + " keyword: "begin" + " where: anywhere in current line + if curs =~? s:NC.'\<begin\>' + " find previous opening statement of + " keywords: "architecture", "block", "entity", "function", "generate", "procedure", "process" + let s2 = s:NC.s:NE.'\<\%(architecture\|block\|entity\|function\|generate\|procedure\|process\)\>' + + let pn = prevnonblank(curn - 1) + let ps = getline(pn) + while pn > 0 && (ps =~ '^\s*--' || ps !~? s2) + let pn = prevnonblank(pn - 1) + let ps = getline(pn) + + if (ps =~? s:NC.'\<begin\>') + return indent(pn) - shiftwidth() + endif + endwhile + + if (pn == 0) + return ind - shiftwidth() + else + return indent(pn) + endif + endif + + " indent: +sw if previous line is previous opening statement + " keywords: "record", "units" + " where: anywhere in current line + if curs =~? s:NC.s:NE.'\<\%(record\|units\)\>' + " find previous opening statement of + " keyword: "type" + let s3 = s:NC.s:NE.'\<type\>' + if curs !~? s3.'.*'.s:NC.'\<\%(record\|units\)\>.*'.s:ES && prevs =~? s3 + let ind = ind + shiftwidth() + endif + return ind + endif + + " **************************************************************************************** + " indent: 0 + " keywords: "architecture", "configuration", "entity", "library", "package" + " where: start of current line + if curs =~? '^\s*\%(architecture\|configuration\|entity\|library\|package\)\>' + return 0 + endif + + " indent: maintain indent of previous opening statement + " keyword: "is" + " where: start of current line + " find previous opening statement of + " keywords: "architecture", "block", "configuration", "entity", "function", "package", "procedure", "process", "type" + if curs =~? '^\s*\<is\>' && prevs =~? s:NC.s:NE.'\<\%(architecture\|block\|configuration\|entity\|function\|package\|procedure\|process\|type\)\>' + return ind2 + endif + + " indent: maintain indent of previous opening statement + " keyword: "then" + " where: start of current line + " find previous opening statement of + " keywords: "elsif", "if" + if curs =~? '^\s*\<then\>' && prevs =~? s:NC.'\%(\<elsif\>\|'.s:NE.'\<if\>\)' + return ind2 + endif + + " indent: maintain indent of previous opening statement + " keyword: "generate" + " where: start of current line + " find previous opening statement of + " keywords: "for", "if" + if curs =~? '^\s*\<generate\>' && prevs =~? s:NC.s:NE.'\%(\%(\<wait\s\+\)\@<!\<for\|\<if\)\>' + return ind2 + endif + + " indent: +sw + " keywords: "block", "process" + " removed: "begin", "case", "elsif", "if", "loop", "record", "units", "while" + " where: anywhere in previous line + if prevs =~? s:NC.s:NE.'\<\%(block\|process\)\>' + return ind + shiftwidth() + endif + + " indent: +sw + " keywords: "architecture", "configuration", "entity", "package" + " removed: "component", "for", "when", "with" + " where: start of previous line + if prevs =~? '^\s*\%(architecture\|configuration\|entity\|package\)\>' + return ind + shiftwidth() + endif + + " indent: +sw + " keyword: "select" + " removed: "generate", "is", "=>" + " where: end of previous line + if prevs =~? s:NC.'\<select'.s:ES + return ind + shiftwidth() + endif + + " indent: +sw + " keyword: "begin", "loop", "record", "units" + " where: anywhere in previous line + " keyword: "component", "else", "for" + " where: start of previous line + " keyword: "generate", "is", "then", "=>" + " where: end of previous line + " _note_: indent allowed to leave this filter + if prevs =~? s:NC.'\%(\<begin\>\|'.s:NE.'\<\%(loop\|record\|units\)\>\)' || prevs =~? '^\s*\%(component\|else\|for\)\>' || prevs =~? s:NC.'\%('.s:NE.'\<generate\|\<\%(is\|then\)\|=>\)'.s:ES + let ind = ind + shiftwidth() + endif + + " **************************************************************************************** + " indent: -sw + " keywords: "when", provided previous line does not begin with "when", does not end with "is" + " where: start of current line + let s4 = '^\s*when\>' + if curs =~? s4 + if prevs =~? s:NC.'\<is'.s:ES + return ind + elseif prevs !~? s4 + return ind - shiftwidth() + else + return ind2 + endif + endif + + " indent: -sw + " keywords: "else", "elsif", "end" + "block", "for", "function", "generate", "if", "loop", "procedure", "process", "record", "units" + " where: start of current line + let s5 = 'block\|for\|function\|generate\|if\|loop\|procedure\|process\|record\|units' + if curs =~? '^\s*\%(else\|elsif\|end\s\+\%('.s5.'\)\)\>' + if prevs =~? '^\s*\%(elsif\|'.s5.'\)' + return ind + else + return ind - shiftwidth() + endif + endif + + " indent: backtrace previous non-comment lines + " keyword: "end" + "case", "component" + " where: start of current line + let m = 0 + if curs =~? '^\s*end\s\+case\>' + let m = 1 + elseif curs =~? '^\s*end\s\+component\>' + let m = 2 + endif + + if m > 0 + " find following previous non-comment line + let pn = prevn + let ps = getline(pn) + while pn > 0 + if ps !~ '^\s*--' + "indent: -2sw + "keywords: "end" + "case" + "where: start of previous non-comment line + "indent: -sw + "keywords: "when" + "where: start of previous non-comment line + "indent: follow + "keywords: "case" + "where: start of previous non-comment line + if m == 1 + if ps =~? '^\s*end\s\+case\>' + return indent(pn) - 2 * shiftwidth() + elseif ps =~? '^\s*when\>' + return indent(pn) - shiftwidth() + elseif ps =~? '^\s*case\>' + return indent(pn) + endif + "indent: follow + "keyword: "component" + "where: start of previous non-comment line + elseif m == 2 + if ps =~? '^\s*component\>' + return indent(pn) + endif + endif + endif + let pn = prevnonblank(pn - 1) + let ps = getline(pn) + endwhile + return ind - shiftwidth() + endif + + " indent: -sw + " keyword: ")" + " where: start of current line + if curs =~ '^\s*)' + return ind - shiftwidth() + endif + + " indent: 0 + " keywords: "end" + "architecture", "configuration", "entity", "package" + " where: start of current line + if curs =~? '^\s*end\s\+\%(architecture\|configuration\|entity\|package\)\>' + return 0 + endif + + " indent: -sw + " keywords: "end" + identifier, ";" + " where: start of current line + "if curs =~? '^\s*end\s\+\w\+\>' + if curs =~? '^\s*end\%(\s\|;'.s:ES.'\)' + return ind - shiftwidth() + endif + + " **************************************************************************************** + " indent: maintain indent of previous opening statement + " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=" + "in", "out", "inout", "buffer", "linkage", variable & ":=" + " where: start of current line + if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)' + return ind2 + endif + + " **************************************************************************************** + " indent: maintain indent of previous opening statement, corner case which + " does not end in ;, but is part of a mapping + " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=", never + ;$ and + " prevline without "procedure", "generic", "map", "port" + ":" but not ":=" + eventually ;$ + " where: start of current line + if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=].*[^;].*$' + if prevs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=].*;.*$' + return ind2 + endif + endif + + " return leftover filtered indent + return ind +endfunction + +endif diff --git a/indent/vim.vim b/indent/vim.vim new file mode 100644 index 00000000..c819c64f --- /dev/null +++ b/indent/vim.vim @@ -0,0 +1,134 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vim') == -1 + +" Vim indent file +" Language: Vim script +" Maintainer: Bram Moolenaar <Bram@vim.org> +" Last Change: 2020 Sep 27 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetVimIndent() +setlocal indentkeys+==end,=},=else,=cat,=finall,=END,0\\,0=\"\\\ +setlocal indentkeys-=0# + +let b:undo_indent = "setl indentkeys< indentexpr<" + +" Only define the function once. +if exists("*GetVimIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +function GetVimIndent() + let ignorecase_save = &ignorecase + try + let &ignorecase = 0 + return GetVimIndentIntern() + finally + let &ignorecase = ignorecase_save + endtry +endfunc + +let s:lineContPat = '^\s*\(\\\|"\\ \)' + +function GetVimIndentIntern() + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " If the current line doesn't start with '\' or '"\ ' and below a line that + " starts with '\' or '"\ ', use the indent of the line above it. + let cur_text = getline(v:lnum) + if cur_text !~ s:lineContPat + while lnum > 0 && getline(lnum) =~ s:lineContPat + let lnum = lnum - 1 + endwhile + endif + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + let prev_text = getline(lnum) + + " Add a 'shiftwidth' after :if, :while, :try, :catch, :finally, :function + " and :else. Add it three times for a line that starts with '\' or '"\ ' + " after a line that doesn't (or g:vim_indent_cont if it exists). + let ind = indent(lnum) + + " In heredoc indenting works completely differently. + if has('syntax_items') + let syn_here = synIDattr(synID(v:lnum, 1, 1), "name") + if syn_here =~ 'vimLetHereDocStop' + " End of heredoc: use indent of matching start line + let lnum = v:lnum - 1 + while lnum > 0 + if synIDattr(synID(lnum, 1, 1), "name") !~ 'vimLetHereDoc' + return indent(lnum) + endif + let lnum -= 1 + endwhile + return 0 + endif + if syn_here =~ 'vimLetHereDoc' + if synIDattr(synID(lnum, 1, 1), "name") !~ 'vimLetHereDoc' + " First line in heredoc: increase indent + return ind + shiftwidth() + endif + " Heredoc continues: no change in indent + return ind + endif + endif + + if cur_text =~ s:lineContPat && v:lnum > 1 && prev_text !~ s:lineContPat + if exists("g:vim_indent_cont") + let ind = ind + g:vim_indent_cont + else + let ind = ind + shiftwidth() * 3 + endif + elseif prev_text =~ '^\s*aug\%[roup]\s\+' && prev_text !~ '^\s*aug\%[roup]\s\+[eE][nN][dD]\>' + let ind = ind + shiftwidth() + else + " A line starting with :au does not increment/decrement indent. + if prev_text !~ '^\s*au\%[tocmd]' + let i = match(prev_text, '\(^\||\)\s*\(export\s\+\)\?\({\|\(if\|wh\%[ile]\|for\|try\|cat\%[ch]\|fina\|finall\%[y]\|fu\%[nction]\|def\|el\%[seif]\)\>\)') + if i >= 0 + let ind += shiftwidth() + if strpart(prev_text, i, 1) == '|' && has('syntax_items') + \ && synIDattr(synID(lnum, i, 1), "name") =~ '\(Comment\|String\)$' + let ind -= shiftwidth() + endif + endif + endif + endif + + " If the previous line contains an "end" after a pipe, but not in an ":au" + " command. And not when there is a backslash before the pipe. + " And when syntax HL is enabled avoid a match inside a string. + let i = match(prev_text, '[^\\]|\s*\(ene\@!\)') + if i > 0 && prev_text !~ '^\s*au\%[tocmd]' + if !has('syntax_items') || synIDattr(synID(lnum, i + 2, 1), "name") !~ '\(Comment\|String\)$' + let ind = ind - shiftwidth() + endif + endif + + + " Subtract a 'shiftwidth' on a :endif, :endwhile, :catch, :finally, :endtry, + " :endfun, :enddef, :else and :augroup END. + if cur_text =~ '^\s*\(ene\@!\|}\|cat\|finall\|el\|aug\%[roup]\s\+[eE][nN][dD]\)' + let ind = ind - shiftwidth() + endif + + return ind +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vim:sw=2 + +endif diff --git a/indent/vroom.vim b/indent/vroom.vim new file mode 100644 index 00000000..9ed918c6 --- /dev/null +++ b/indent/vroom.vim @@ -0,0 +1,25 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vroom') == -1 + +" Vim indent file +" Language: Vroom (vim testing and executable documentation) +" Maintainer: David Barnett (https://github.com/google/vim-ft-vroom) +" Last Change: 2014 Jul 23 + +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +let s:cpo_save = &cpo +set cpo-=C + + +let b:undo_indent = 'setlocal autoindent<' + +setlocal autoindent + + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/wast.vim b/indent/wast.vim new file mode 100644 index 00000000..abc5bfbd --- /dev/null +++ b/indent/wast.vim @@ -0,0 +1,21 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'wast') == -1 + +" Vim indent file +" Language: WebAssembly +" Maintainer: rhysd <lin90162@yahoo.co.jp> +" Last Change: Jul 29, 2018 +" For bugs, patches and license go to https://github.com/rhysd/vim-wasm + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" WebAssembly text format is S-expression. We can reuse LISP indentation +" logic. +setlocal indentexpr=lispindent('.') +setlocal noautoindent nosmartindent + +let b:undo_indent = "setl lisp< indentexpr<" + +endif diff --git a/indent/xhtml.vim b/indent/xhtml.vim new file mode 100644 index 00000000..abe08ba3 --- /dev/null +++ b/indent/xhtml.vim @@ -0,0 +1,16 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'xhtml') == -1 + +" Vim indent file +" Language: XHTML +" Maintainer: Bram Moolenaar <Bram@vim.org> (for now) +" Last Change: 2005 Jun 24 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" Handled like HTML for now. +runtime! indent/html.vim + +endif diff --git a/indent/xinetd.vim b/indent/xinetd.vim new file mode 100644 index 00000000..4ee1a76f --- /dev/null +++ b/indent/xinetd.vim @@ -0,0 +1,59 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'xinetd') == -1 + +" Vim indent file +" Language: xinetd.conf(5) configuration file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetXinetdIndent() +setlocal indentkeys=0{,0},!^F,o,O +setlocal nosmartindent + +if exists("*GetXinetdIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +function s:count_braces(lnum, count_open) + let n_open = 0 + let n_close = 0 + let line = getline(a:lnum) + let pattern = '[{}]' + let i = match(line, pattern) + while i != -1 + if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'ld\%(Comment\|String\)' + if line[i] == '{' + let n_open += 1 + elseif line[i] == '}' + if n_open > 0 + let n_open -= 1 + else + let n_close += 1 + endif + endif + endif + let i = match(line, pattern, i + 1) + endwhile + return a:count_open ? n_open : n_close +endfunction + +function GetXinetdIndent() + let pnum = prevnonblank(v:lnum - 1) + if pnum == 0 + return 0 + endif + + return indent(pnum) + s:count_braces(pnum, 1) * shiftwidth() + \ - s:count_braces(v:lnum, 0) * shiftwidth() +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +endif diff --git a/indent/xsd.vim b/indent/xsd.vim new file mode 100644 index 00000000..c12f73c7 --- /dev/null +++ b/indent/xsd.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'xsd') == -1 + +" Vim indent file +" Language: .xsd files (XML Schema) +" Maintainer: Nobody +" Last Change: 2005 Jun 09 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" Use XML formatting rules +runtime! indent/xml.vim + + +endif diff --git a/indent/xslt.vim b/indent/xslt.vim new file mode 100644 index 00000000..e31f9aca --- /dev/null +++ b/indent/xslt.vim @@ -0,0 +1,17 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'xslt') == -1 + +" Vim indent file +" Language: XSLT .xslt files +" Maintainer: David Fishburn <fishburn@ianywhere.com> +" Last Change: Wed May 14 2003 8:48:41 PM + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" Use XML formatting rules +runtime! indent/xml.vim + + +endif diff --git a/indent/yacc.vim b/indent/yacc.vim new file mode 100644 index 00000000..9ebb7f49 --- /dev/null +++ b/indent/yacc.vim @@ -0,0 +1,45 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'yacc') == -1 + +" Vim indent file +" Language: YACC input file +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2006-12-20 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +let b:did_indent = 1 + +setlocal indentexpr=GetYaccIndent() +setlocal indentkeys=!^F,o,O +setlocal nosmartindent + +" Only define the function once. +if exists("*GetYaccIndent") + finish +endif + +function GetYaccIndent() + if v:lnum == 1 + return 0 + endif + + let ind = indent(v:lnum - 1) + let line = getline(v:lnum - 1) + + if line == '' + let ind = 0 + elseif line =~ '^\w\+\s*:' + let ind = ind + matchend(line, '^\w\+\s*') + elseif line =~ '^\s*;' + let ind = 0 + else + let ind = indent(v:lnum) + endif + + return ind +endfunction + +endif diff --git a/indent/yaml.vim b/indent/yaml.vim deleted file mode 100644 index c7fdebcf..00000000 --- a/indent/yaml.vim +++ /dev/null @@ -1,159 +0,0 @@ -if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'yaml') == -1 - -" Vim indent file -" Language: YAML -" Maintainer: Nikolai Pavlov <zyx.vim@gmail.com> -" Last Change: 2019 Sep 28 - -" Only load this indent file when no other was loaded. -if exists('b:did_indent') - finish -endif - -let s:save_cpo = &cpo -set cpo&vim - -let b:did_indent = 1 - -setlocal indentexpr=GetYAMLIndent(v:lnum) -setlocal indentkeys=!^F,o,O,0#,0},0],<:>,0- -setlocal nosmartindent - -let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<' - -" Only define the function once. -if exists('*GetYAMLIndent') - finish -endif - -function s:FindPrevLessIndentedLine(lnum, ...) - let prevlnum = prevnonblank(a:lnum-1) - let curindent = a:0 ? a:1 : indent(a:lnum) - while prevlnum - \&& indent(prevlnum) >= curindent - \&& getline(prevlnum) !~# '^\s*#' - let prevlnum = prevnonblank(prevlnum-1) - endwhile - return prevlnum -endfunction - -function s:FindPrevLEIndentedLineMatchingRegex(lnum, regex) - let plilnum = s:FindPrevLessIndentedLine(a:lnum, indent(a:lnum)+1) - while plilnum && getline(plilnum) !~# a:regex - let plilnum = s:FindPrevLessIndentedLine(plilnum) - endwhile - return plilnum -endfunction - -let s:mapkeyregex='\v^\s*\#@!\S@=%(\''%([^'']|\''\'')*\'''. - \ '|\"%([^"\\]|\\.)*\"'. - \ '|%(%(\:\ )@!.)*)\:%(\ |$)' -let s:liststartregex='\v^\s*%(\-%(\ |$))' - -let s:c_ns_anchor_char = '\v%([\n\r\uFEFF \t,[\]{}]@!\p)' -let s:c_ns_anchor_name = s:c_ns_anchor_char.'+' -let s:c_ns_anchor_property = '\v\&'.s:c_ns_anchor_name - -let s:ns_word_char = '\v[[:alnum:]_\-]' -let s:ns_tag_char = '\v%(%\x\x|'.s:ns_word_char.'|[#/;?:@&=+$.~*''()])' -let s:c_named_tag_handle = '\v\!'.s:ns_word_char.'+\!' -let s:c_secondary_tag_handle = '\v\!\!' -let s:c_primary_tag_handle = '\v\!' -let s:c_tag_handle = '\v%('.s:c_named_tag_handle. - \ '|'.s:c_secondary_tag_handle. - \ '|'.s:c_primary_tag_handle.')' -let s:c_ns_shorthand_tag = '\v'.s:c_tag_handle . s:ns_tag_char.'+' -let s:c_non_specific_tag = '\v\!' -let s:ns_uri_char = '\v%(%\x\x|'.s:ns_word_char.'\v|[#/;?:@&=+$,.!~*''()[\]])' -let s:c_verbatim_tag = '\v\!\<'.s:ns_uri_char.'+\>' -let s:c_ns_tag_property = '\v'.s:c_verbatim_tag. - \ '\v|'.s:c_ns_shorthand_tag. - \ '\v|'.s:c_non_specific_tag - -let s:block_scalar_header = '\v[|>]%([+-]?[1-9]|[1-9]?[+-])?' - -function GetYAMLIndent(lnum) - if a:lnum == 1 || !prevnonblank(a:lnum-1) - return 0 - endif - - let prevlnum = prevnonblank(a:lnum-1) - let previndent = indent(prevlnum) - - let line = getline(a:lnum) - if line =~# '^\s*#' && getline(a:lnum-1) =~# '^\s*#' - " Comment blocks should have identical indent - return previndent - elseif line =~# '^\s*[\]}]' - " Lines containing only closing braces should have previous indent - return indent(s:FindPrevLessIndentedLine(a:lnum)) - endif - - " Ignore comment lines when calculating indent - while getline(prevlnum) =~# '^\s*#' - let prevlnum = prevnonblank(prevlnum-1) - if !prevlnum - return previndent - endif - endwhile - - let prevline = getline(prevlnum) - let previndent = indent(prevlnum) - - " Any examples below assume that shiftwidth=2 - if prevline =~# '\v[{[:]$|[:-]\ [|>][+\-]?%(\s+\#.*|\s*)$' - " Mapping key: - " nested mapping: ... - " - " - { - " key: [ - " list value - " ] - " } - " - " - |- - " Block scalar without indentation indicator - return previndent+shiftwidth() - elseif prevline =~# '\v[:-]\ [|>]%(\d+[+\-]?|[+\-]?\d+)%(\#.*|\s*)$' - " - |+2 - " block scalar with indentation indicator - "#^^ indent+2, not indent+shiftwidth - return previndent + str2nr(matchstr(prevline, - \'\v([:-]\ [|>])@<=[+\-]?\d+%([+\-]?%(\s+\#.*|\s*)$)@=')) - elseif prevline =~# '\v\"%([^"\\]|\\.)*\\$' - " "Multiline string \ - " with escaped end" - let qidx = match(prevline, '\v\"%([^"\\]|\\.)*\\') - return virtcol([prevlnum, qidx+1]) - elseif line =~# s:liststartregex - " List line should have indent equal to previous list line unless it was - " caught by one of the previous rules - return indent(s:FindPrevLEIndentedLineMatchingRegex(a:lnum, - \ s:liststartregex)) - elseif line =~# s:mapkeyregex - " Same for line containing mapping key - let prevmapline = s:FindPrevLEIndentedLineMatchingRegex(a:lnum, - \ s:mapkeyregex) - if getline(prevmapline) =~# '^\s*- ' - return indent(prevmapline) + 2 - else - return indent(prevmapline) - endif - elseif prevline =~# '^\s*- ' - " - List with - " multiline scalar - return previndent+2 - elseif prevline =~# s:mapkeyregex . '\v\s*%(%('.s:c_ns_tag_property. - \ '\v|'.s:c_ns_anchor_property. - \ '\v|'.s:block_scalar_header. - \ '\v)%(\s+|\s*%(\#.*)?$))*' - " Mapping with: value - " that is multiline scalar - return previndent+shiftwidth() - endif - return previndent -endfunction - -let &cpo = s:save_cpo - -endif diff --git a/indent/zimbu.vim b/indent/zimbu.vim new file mode 100644 index 00000000..20354401 --- /dev/null +++ b/indent/zimbu.vim @@ -0,0 +1,132 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'zimbu') == -1 + +" Vim indent file +" Language: Zimbu +" Maintainer: Bram Moolenaar <Bram@vim.org> +" Last Change: 2016 Jan 25 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal ai nolisp nocin +setlocal indentexpr=GetZimbuIndent(v:lnum) +setlocal indentkeys=0{,0},!^F,o,O,0=ELSE,0=ELSEIF,0=CASE,0=DEFAULT,0=FINALLY + +" We impose recommended defaults: no Tabs, 'shiftwidth' = 2 +setlocal sw=2 et + +let b:undo_indent = "setl et< sw< ai< indentkeys< indentexpr=" + +" Only define the function once. +if exists("*GetZimbuIndent") + finish +endif + +let s:cpo_save = &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 () + +func GetZimbuIndent(lnum) + let prevLnum = prevnonblank(a:lnum - 1) + if prevLnum == 0 + " This is the first non-empty line, use zero indent. + return 0 + endif + + " Taken from Python indenting: + " 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(prevLnum, 1) + let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW', + \ "line('.') < " . (prevLnum - s:maxoff) . " ? dummy :" + \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" + \ . " =~ '\\(Comment\\|String\\|Char\\)$'") + if parlnum > 0 + let plindent = indent(parlnum) + let plnumstart = parlnum + else + let plindent = indent(prevLnum) + let plnumstart = prevLnum + 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\\|String\\|Char\\)$'") + if p > 0 + if p == prevLnum + " 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\\|String\\|Char\\)$'") + if pp > 0 + return indent(prevLnum) + shiftwidth() + endif + return indent(prevLnum) + shiftwidth() * 2 + endif + if plnumstart == p + return indent(prevLnum) + endif + return plindent + endif + + let prevline = getline(prevLnum) + let thisline = getline(a:lnum) + + " If this line is not a comment and the previous one is then move the + " previous line further back. + if thisline !~ '^\s*#' + while prevline =~ '^\s*#' + let prevLnum = prevnonblank(prevLnum - 1) + if prevLnum == 0 + " Only comment lines before this, no indent + return 0 + endif + let prevline = getline(prevLnum) + let plindent = indent(prevLnum) + endwhile + endif + + if prevline =~ '^\s*\(IF\|\|ELSEIF\|ELSE\|GENERATE_IF\|\|GENERATE_ELSEIF\|GENERATE_ELSE\|WHILE\|REPEAT\|TRY\|CATCH\|FINALLY\|FOR\|DO\|SWITCH\|CASE\|DEFAULT\|FUNC\|VIRTUAL\|ABSTRACT\|DEFINE\|REPLACE\|FINAL\|PROC\|MAIN\|NEW\|ENUM\|CLASS\|INTERFACE\|BITS\|MODULE\|SHARED\)\>' + let plindent += shiftwidth() + endif + if thisline =~ '^\s*\(}\|ELSEIF\>\|ELSE\>\|CATCH\|FINALLY\|GENERATE_ELSEIF\>\|GENERATE_ELSE\>\|UNTIL\>\)' + let plindent -= shiftwidth() + endif + if thisline =~ '^\s*\(CASE\>\|DEFAULT\>\)' && prevline !~ '^\s*SWITCH\>' + let plindent -= shiftwidth() + endif + + " line up continued comment that started after some code + " String something # comment comment + " # comment + if a:lnum == prevLnum + 1 && thisline =~ '^\s*#' && prevline !~ '^\s*#' + let n = match(prevline, '#') + if n > 1 + let plindent = n + endif + endif + + return plindent +endfunc + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif |