xref: /vim-8.2.3635/runtime/indent/verilog.vim (revision 2bf24176)
1" Language:     Verilog HDL
2" Maintainer:	Chih-Tsun Huang <[email protected]>
3" Last Change:	2011 Dec 10 by Thilo Six
4" 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 <[email protected]>
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
33let s:cpo_save = &cpo
34set cpo&vim
35
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
220let &cpo = s:cpo_save
221unlet s:cpo_save
222
223" vim:sw=2
224