I was able to reproduce this with a vhdl filetype, using filetype indentation.
:set filetype? --> vhdl
:filetype --> filetype detection:ON plugin:ON indent:ON
I noticed that the error described is only happening when there were no non-comment, non-empty lines between the if and end if; lines:
if xxx then
SOMETHING <= '1';
end if;
if xxx then
end if;
The error is caused by this part of the $VIMRUNTIME/indent/vhdl.vim file. If the current string contains end if and the previous line's string contains if, then return the number ind.
" indent: -sw
" keywords: "else", "elsif", "end" + "block", "for", "function", "generate", "if", "loop", "procedure", "process", "record", "units"
" where: start of current line
let s5 = 'block\|for\|function\|generate\|if\|loop\|procedure\|process\|record\|units'
if curs =~? '^\s*\%(else\|elsif\|end\s\+\%('.s5.'\)\)\>'
if prevs =~? '^\s*\%(elsif\|'.s5.'\)'
return ind
else
return ind - shiftwidth()
endif
endif
Earlier in the script, the value of ind is increased by a shiftwidth() if the previous line contains then. Later in the script, the value of ind is decreased by a shiftwidth() is end matches the current line. This is the intended behavior, but the above return ind prevents that from happening.
Solution
Comment out the return ind line.
" indent: -sw
" keywords: "else", "elsif", "end" + "block", "for", "function", "generate", "if", "loop", "procedure", "process", "record", "units"
" where: start of current line
let s5 = 'block\|for\|function\|generate\|if\|loop\|procedure\|process\|record\|units'
if curs =~? '^\s*\%(else\|elsif\|end\s\+\%('.s5.'\)\)\>'
if prevs =~? '^\s*\%(elsif\|'.s5.'\)'
" DO NOTHING. COMMENT OUT LINE BELOW
" return ind
else
return ind - shiftwidth()
endif
endif
If you can't edit your $VIMRUNTIME/indent/vhdl.vim file, you'll need to copy it to ~/.vim/indent/vhdl.vim first. When you restart Vim with a vhdl file, it will use your local override.
Please also report this as an issue at https://github.com/vim/vim