From c0b4c7f49b75b65f85249fd20105644d99b2fd39 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Mon, 3 Aug 2009 12:02:05 -0400 Subject: [PATCH] misc: vim: better indentation of closures Signed-off-by: Jean Privat --- misc/vim/indent/nit.vim | 65 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/misc/vim/indent/nit.vim b/misc/vim/indent/nit.vim index 784e552..0b18e7d 100644 --- a/misc/vim/indent/nit.vim +++ b/misc/vim/indent/nit.vim @@ -30,16 +30,28 @@ setlocal nosmartindent setlocal nocindent setlocal autoindent setlocal comments=:# -setlocal indentkeys+==end,=else,=do,=var,=with,=then,=special,=class,=interface,=universal +setlocal indentkeys+==end,=else,=do,=var,0!,=then,=special,=class,=interface,=universal setlocal sw=8 " Indent after -let s:relative_indent = '\<\(do\|then\|else\|if\)\s*$\|^\s*\(\<\(redef\|private\)\>\s*\)\?\(\\s*\)\?\<\(class\|interface\|universal\|special\)\>' +let s:relative_indent = '\<\(do\|then\|else\|if\)\s*\(#\|$\)\|^\s*\(\<\(redef\|private\)\>\s*\)\?\(\\s*\)\?\<\(class\|interface\|universal\|special\)\>' " Unindent on them -let s:outdent = '^\s*\(else\|then\|with\|end\)\>' +let s:outdent = '^\s*\(else\|then\|end\)\>' " At 0 let s:no_indent = '^\s*\(class\|import\|special\)\>' +let s:syng_strcom = '\' + +" 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, 0), 'name') =~ s:syng_strcom +endfunction + +function s:Match(lnum, regex) + let col = match(getline(a:lnum), a:regex) + 1 + return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +endfunction + " Only define the function once. if exists("*GetNITIndent") finish @@ -47,35 +59,58 @@ endif function GetNITIndent() " Find a non-blank line above the current line. - let lnum = prevnonblank(v:lnum - 1) + let plnum = prevnonblank(v:lnum - 1) " At the start of the file use zero indent. - if lnum == 0 + if plnum == 0 return 0 endif let cline = getline(v:lnum) " The line to indent - let prevline=getline(lnum) " The previous nonempty line - let ind = indent(lnum) " The previous nonempty indent level + let prevline=getline(plnum) " The previous nonempty line + let ind = indent(plnum) " The previous nonempty indent level " Add a 'shiftwidth' after lines that start with an indent word - if prevline =~ s:relative_indent + if s:Match(plnum, s:relative_indent) + "if prevline =~ s:relative_indent let ind = ind + &sw endif " Subtract a 'shiftwidth', for lines that start with an outdent word - if cline =~ s:outdent + "if cline =~ s:outdent + if s:Match(v:lnum, s:outdent) let ind = ind - &sw endif - " The following should always be at the start of a line, no indenting - if cline =~ s:no_indent - let ind = 0 + " Unindent line after a closure declaration + if prevline =~ '^\s*\(break\)\=\s*!' + let col = match(prevline, "!") + let ctx = synIDattr(synID(plnum, col, 0), 'name') + echo "prev is " ctx + if ctx !~ "NITStmtBlock" + " closure declaration + let ind = ind - &sw + end endif - " Subtract a shiftwidth for end statements - if prevline =~ '$\s*end\s*\(#|$\)' - let ind = ind - &sw + " Indent line of a closure declaration + " Unindent line of a closure definition + if cline =~ '^\s*\(break\)\=\s*!' + let col = match(cline, "!") + let ctx = synIDattr(synID(v:lnum, col, 0), 'name') + if ctx =~ "NITStmtBlock" + " closure definition + let ind = ind - &sw + else + " closure declaration + let ind = ind + &sw + end + endif + + " The following should always be at the start of a line, no indenting + "if cline =~ s:no_indent + if s:Match(v:lnum, s:no_indent) + let ind = 0 endif return ind -- 1.7.9.5