Reputation: 333
When I edit a vhdl file using vim or neovim, the “if-else-end if;” statement never autoindent properly. When I typed “if xxx then” and Enter, it looks like as follows:
if xxx then
|
which is fine. Then I keep typing “end” and a Space, the it looks like:
if xxx then
end |
After I finish the statement by typing “if;”, then it looks like follows:
if xxx then
end if;
So, how can I fix this?
The filetype is vhdl, the vim version is 8.2, and the script loaded by vim that implements vhdl indention is /usr/share/vim/vim82/indent/vhdl.vim.
Upvotes: 2
Views: 424
Reputation: 1863
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
Upvotes: 3