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