HOME BLOG ARCHIVE TAGS

Playing with Smart-Tabs

February 28, 2016

Tabs vs spaces for indentation: which scheme is better?

I prefer tabs. They are adjustable, and afford some flexibility when sharing code. Others chose spaces for portability and strict control.

Both camps have relevant arguments; e.g., Python Style Guide defines spaces as the preferred method, while Linux Coding Style takes tab side.

If spaces are not introduced as padding, perfect alignment is not possible with tabs. But mixing them becomes ugly the moment original tab size is redefined. Example adapted from EmacsWiki:

1
2
3
4
5
  // tab size: 4              // tab size: 8
  if ( some_condition ) {     if ( some_condition ) {
  <-->foo(a, b, c, d,         <------>foo(a, b, c, d,      // lost
  <--><-->e, f, g, h);        <------><------>e, f, g, h); // alignment
  }                           }

That’s why I’m playing with Smart-Tabs, a semantic way of indenting source code:

1
2
3
4
5
6
7
8
9
  //
  // tabs express levels of indentation; alignment is done with spaces;
  //

  // tab size: 4              // tab size: 8
  if ( some_condition ) {     if ( some_condition ) {
  <-->foo(a, b, c, d,         <------>foo(a, b, c, d,  // kept
  <-->....e, f, g, g);        <------>....e, f, g, g); // alignment
  }                           }

A good editor helps to enforce this approach in practice. For Emacs, SmartTabs package does a nice job, coupled with customizations that force space alignment in other circumstances:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
;; align.el reads indent-tabs-mode directly, so an advice is used
;; to disable it, avoiding alignment with tabs

(defadvice align (around align-with-sp activate)
  "Force alignment with spaces."
  (let ((indent-tabs-mode nil)) ad-do-it))

;; same principle, for c multiline '\' regions
(defadvice c-backslash-region (around c-backslash-region-with-sp activate)
  "Force c-backslash-region alignment with spaces."
  (let ((indent-tabs-mode nil)) ad-do-it))