February 15, 2018

Vim and tabs

Languages like Haskell and Python use indentation as part of the language syntax. This is a topic of intense debate and conflict, but ultimately it is what it is and you have to deal with it. In particular, if you are a vim user, you have to come to grips with tab related settings to have a sane experience with these languages. As currently configured on my system, Haskell gives the following warning when it sees tabs in a source file:
warning: [-Wtabs]
Tab character found here.
Please use spaces instead.
The only sensible approach with these languages is to make sure that tabs never end up in a source file. If you are like me, you have a huge amount of code written in C and would like to let that sleeping dog lie. This leads to a desire to have vim use one set of settings for C and another set for Haskell and Python. It is not terribly hard to do this. In truth though, there would be no harm in turning on the expandtab option for C code. This would produce spaces for any new editing, but leave any old tabs alone. And the file would look just the same either way

For now I am just trying to rationalize my Haskell experience, but I expect that the methodology I use will transfer neatly to Python as well.

The Haskell wiki recommends these settings and suggests that you put them into ~/.vim/plugin/Haskell.vim
" Tab specific option
set tabstop=8                   "A tab is 8 spaces
set expandtab                   "Always uses spaces instead of tabs
set softtabstop=4               "Insert 4 spaces when tab is pressed
set shiftwidth=4                "An indent is 4 spaces
set shiftround                  "Round indent to nearest shiftwidth multiple
what I currently have now in my .vimrc is:
" Let's see if this gives us sane tabs
set shiftwidth=4
set shiftround
set tabstop=8
" set softtabstop=0
set softtabstop=4
set smarttab

" We do NOT want expandtab
" it would convert all tabs to spaces
" This would break make if nothing else
" set expandtab
set noexpandtab

" the following will make an exception just for make
" if we ever start using just spaces, as perhaps we should
autocmd FileType make setlocal noexpandtab
Comparing what I have with the Haskell recommendations indicates that the main difference is the "expandtab" versus "noexpandtab" option.

Expandtab will cause vim to insert an appropriate number of tabs into your file whenever you hit the tab key. If you have a file that already contains tabs, you can get rid of them using the :retab command. (Be sure and have the expandtab and tabstop setting correct first). This works well.

After all the smoke clears, all I need to do is add this to my .vimrc

autocmd FileType haskell setlocal expandtab

Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org