Difference between revisions of "Emacs/Indentation"

From HaskellWiki
Jump to navigation Jump to search
(First commit.)
 
(Blanked the page)
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Emacs can indent Haskell in various ways. The most common is the tab cycle.
 
 
== Indentation using tab cycle ==
 
 
Haskell-mode offers intelligent indentation. As Haskell source code uses indentation aware code blocks, there is usually more than one column for which indentation makes sense.
 
 
Hit tab a few times to see a few different indentation possibilities.
 
 
For example, imagine the following is open in a haskell-mode buffer, where <code>!</code> represents the point:
 
 
<haskell>
 
foo :: Int -> String
 
foo 0 = f 4 ++ s
 
where f 4 = "hello" ++
 
!
 
</haskell>
 
 
If you ask <code>haskell-mode</code> to indent for you, where should it indent to? There are four basic options:
 
 
<ol>
 
<li>
 
You want to finish off the expression you were writing in the last line. <code>Haskell-mode</code> indents to be underneath the <code>"</code> character at the beginning of <code>"hello"</code>:
 
 
<haskell>
 
where f 4 = "hello" ++
 
!
 
</haskell>
 
 
This is debatably a bad choice as you'd probably want to indent a bit further in to make it clear that you were carrying on an expression, but the layout rule would accept something like the following:
 
 
<haskell>
 
where f 4 = "hello" ++
 
"world"
 
</haskell>
 
 
</li>
 
<li>
 
You want to add a second equation for <code>f</code>. <code>Haskell-mode</code> will indent to line up with the first argument, and fill in the <code>f</code> in the equation:
 
 
<haskell>
 
where f 4 = "hello" ++
 
f !
 
</haskell>
 
 
This is an unlikely choice as the expression in the previous line isn't complete, but <code>haskell-mode</code> isn't smart enough to know that. (If <code>f</code> had been something without arguments, like <hask>where f = "hello"</hask>, then it's impossible to have more than one equation and haskell-mode won't offer this indentation level.)
 
</li>
 
<li>
 
You want to add a second binding to the <code>where</code>-block. Haskell-mode indents to line up with the <code>f</code>:
 
 
<haskell>
 
where f 4 = "hello" ++
 
!
 
</haskell>
 
 
</li>
 
<li>You want to start an entirely new top-level binding. Haskell-mode indents to the first column:
 
 
<haskell>
 
foo :: Int -> String
 
foo 0 = f 4 ++ s
 
where f 4 = "hello" ++
 
!
 
</haskell>
 
 
</li>
 
</ol>
 
 
These four locations can be reached by repeatedly pressing <code>TAB</code>. This is what's known as the tab-cycle. The innermost location is offered first, then cycling progresses outwards. Although this may seem like an inefficient system (and it is indeed a shame that Haskell's design didn't result in an unambiguous indentation system), you do quickly get used to the tab-cycle and indenting Haskell code.
 
 
''Notes:''
 
 
Do not use indent-region
 
 
Using indent-region is generally a bad idea on Haskell code, because it would need to know which of the tab-cycle stops you wish to choose for each line. The innermost one is chosen in each case, which often results in unusable code. Moral: just don't use indent-region with haskell-mode.
 

Revision as of 11:57, 11 April 2016