Merge branch 'hack/autopaste'
[vim-kana.git] / runtime / indent / verilog.vim
blob74c8c5f6ddd200e07e6a8eb52a0d8f441ad16ba5
1 " Language:     Verilog HDL
2 " Maintainer:   Chih-Tsun Huang <cthuang@larc.ee.nthu.edu.tw>
3 " Last Change:  Wed Oct 31 16:13:11 CST 2001
4 " URL:          http://larc.ee.nthu.edu.tw/~cthuang/vim/indent/verilog.vim
6 " Credits:
7 "   Suggestions for improvement, bug reports by
8 "     Leo Butlero <lbutler@brocade.com>
10 " Buffer Variables:
11 "     b:verilog_indent_modules : indenting after the declaration
12 "                                of module blocks
13 "     b:verilog_indent_width   : indenting width
14 "     b:verilog_indent_verbose : verbose to each indenting
17 " Only load this indent file when no other was loaded.
18 if exists("b:did_indent")
19   finish
20 endif
21 let b:did_indent = 1
23 setlocal indentexpr=GetVerilogIndent()
24 setlocal indentkeys=!^F,o,O,0),=begin,=end,=join,=endcase
25 setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify
26 setlocal indentkeys+==`else,=`endif
28 " Only define the function once.
29 if exists("*GetVerilogIndent")
30   finish
31 endif
33 set cpo-=C
35 function GetVerilogIndent()
37   if exists('b:verilog_indent_width')
38     let offset = b:verilog_indent_width
39   else
40     let offset = &sw
41   endif
42   if exists('b:verilog_indent_modules')
43     let indent_modules = offset
44   else
45     let indent_modules = 0
46   endif
48   " Find a non-blank line above the current line.
49   let lnum = prevnonblank(v:lnum - 1)
51   " At the start of the file use zero indent.
52   if lnum == 0
53     return 0
54   endif
56   let lnum2 = prevnonblank(lnum - 1)
57   let curr_line  = getline(v:lnum)
58   let last_line  = getline(lnum)
59   let last_line2 = getline(lnum2)
60   let ind  = indent(lnum)
61   let ind2 = indent(lnum - 1)
62   let offset_comment1 = 1
63   " Define the condition of an open statement
64   "   Exclude the match of //, /* or */
65   let vlog_openstat = '\(\<or\>\|\([*/]\)\@<![*(,{><+-/%^&|!=?:]\([*/]\)\@!\)'
66   " Define the condition when the statement ends with a one-line comment
67   let vlog_comment = '\(//.*\|/\*.*\*/\s*\)'
68   if exists('b:verilog_indent_verbose')
69     let vverb_str = 'INDENT VERBOSE:'
70     let vverb = 1
71   else
72     let vverb = 0
73   endif
75   " Indent accoding to last line
76   " End of multiple-line comment
77   if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/'
78     let ind = ind - offset_comment1
79     if vverb
80       echo vverb_str "De-indent after a multiple-line comment."
81     endif
83   " Indent after if/else/for/case/always/initial/specify/fork blocks
84   elseif last_line =~ '`\@<!\<\(if\|else\)\>' ||
85     \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\)\>' ||
86     \ last_line =~ '^\s*\<\(always\|initial\)\>' ||
87     \ last_line =~ '^\s*\<\(specify\|fork\)\>'
88     if last_line !~ '\(;\|\<end\>\)\s*' . vlog_comment . '*$' ||
89       \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$'
90       let ind = ind + offset
91       if vverb | echo vverb_str "Indent after a block statement." | endif
92     endif
93   " Indent after function/task blocks
94   elseif last_line =~ '^\s*\<\(function\|task\)\>'
95     if last_line !~ '\<end\>\s*' . vlog_comment . '*$' ||
96       \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$'
97       let ind = ind + offset
98       if vverb
99         echo vverb_str "Indent after function/task block statement."
100       endif
101     endif
103   " Indent after module/function/task/specify/fork blocks
104   elseif last_line =~ '^\s*\<module\>'
105     let ind = ind + indent_modules
106     if vverb && indent_modules
107       echo vverb_str "Indent after module statement."
108     endif
109     if last_line =~ '[(,]\s*' . vlog_comment . '*$' &&
110       \ last_line !~ '\(//\|/\*\).*[(,]\s*' . vlog_comment . '*$'
111       let ind = ind + offset
112       if vverb
113         echo vverb_str "Indent after a multiple-line module statement."
114       endif
115     endif
117   " Indent after a 'begin' statement
118   elseif last_line =~ '\(\<begin\>\)\(\s*:\s*\w\+\)*' . vlog_comment . '*$' &&
119     \ last_line !~ '\(//\|/\*\).*\(\<begin\>\)' &&
120     \ ( last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' ||
121     \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . vlog_comment . '*$' )
122     let ind = ind + offset
123     if vverb | echo vverb_str "Indent after begin statement." | endif
125   " De-indent for the end of one-line block
126   elseif ( last_line !~ '\<begin\>' ||
127     \ last_line =~ '\(//\|/\*\).*\<begin\>' ) &&
128     \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>.*' .
129       \ vlog_comment . '*$' &&
130     \ last_line2 !~
131       \ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>' &&
132     \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
133     \ ( last_line2 !~ '\<begin\>' ||
134     \ last_line2 =~ '\(//\|/\*\).*\<begin\>' )
135     let ind = ind - offset
136     if vverb
137       echo vverb_str "De-indent after the end of one-line statement."
138     endif
140     " Multiple-line statement (including case statement)
141     " Open statement
142     "   Ident the first open line
143     elseif  last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
144       \ last_line !~ '\(//\|/\*\).*' . vlog_openstat . '\s*$' &&
145       \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$'
146       let ind = ind + offset
147       if vverb | echo vverb_str "Indent after an open statement." | endif
149     " Close statement
150     "   De-indent for an optional close parenthesis and a semicolon, and only
151     "   if there exists precedent non-whitespace char
152     elseif last_line =~ ')*\s*;\s*' . vlog_comment . '*$' &&
153       \ last_line !~ '^\s*)*\s*;\s*' . vlog_comment . '*$' &&
154       \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . vlog_comment . '*$' &&
155       \ ( last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
156       \ last_line2 !~ ';\s*//.*$') &&
157       \ last_line2 !~ '^\s*' . vlog_comment . '$'
158       let ind = ind - offset
159       if vverb | echo vverb_str "De-indent after a close statement." | endif
161   " `ifdef and `else
162   elseif last_line =~ '^\s*`\<\(ifdef\|else\)\>'
163     let ind = ind + offset
164     if vverb
165       echo vverb_str "Indent after a `ifdef or `else statement."
166     endif
168   endif
170   " Re-indent current line
172   " De-indent on the end of the block
173   " join/end/endcase/endfunction/endtask/endspecify
174   if curr_line =~ '^\s*\<\(join\|end\|endcase\)\>' ||
175     \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\)\>'
176     let ind = ind - offset
177     if vverb | echo vverb_str "De-indent the end of a block." | endif
178   elseif curr_line =~ '^\s*\<endmodule\>'
179     let ind = ind - indent_modules
180     if vverb && indent_modules
181       echo vverb_str "De-indent the end of a module."
182     endif
184   " De-indent on a stand-alone 'begin'
185   elseif curr_line =~ '^\s*\<begin\>'
186     if last_line !~ '^\s*\<\(function\|task\|specify\|module\)\>' &&
187       \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . vlog_comment . '*$' &&
188       \ ( last_line =~
189         \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\)\>' ||
190       \ last_line =~ ')\s*' . vlog_comment . '*$' ||
191       \ last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' )
192       let ind = ind - offset
193       if vverb
194         echo vverb_str "De-indent a stand alone begin statement."
195       endif
196     endif
198   " De-indent after the end of multiple-line statement
199   elseif curr_line =~ '^\s*)' &&
200     \ ( last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' ||
201     \ last_line !~ vlog_openstat . '\s*' . vlog_comment . '*$' &&
202     \ last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' )
203     let ind = ind - offset
204     if vverb
205       echo vverb_str "De-indent the end of a multiple statement."
206     endif
208   " De-indent `else and `endif
209   elseif curr_line =~ '^\s*`\<\(else\|endif\)\>'
210     let ind = ind - offset
211     if vverb | echo vverb_str "De-indent `else and `endif statement." | endif
213   endif
215   " Return the indention
216   return ind
217 endfunction
219 " vim:sw=2