neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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