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