Difference between revisions of "Emacs/Indentation"
< Emacs
Jump to navigation
Jump to search
m (Added infobox.) |
m (To be deleted if no new content appears...) |
||
(7 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | [[Category: |
+ | [[Category:Pages to be removed]] |
− | {{Haskell infobox}} |
||
− | |||
− | = Indentation Approaches = |
||
− | |||
− | 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. |
||
− | |||
− | == Using rectangular region commands == |
||
− | |||
− | Emacs has a set of commands which operate on the region as if it were rectangular. This turns out to be extremely useful when dealing with whitespace sensitive languages. |
||
− | |||
− | <code>C-x r o</code> is "Open Rectangle". It will shift any text within the rectangle to the right side. Also see: |
||
− | |||
− | <code>C-x r t</code> is "String Rectangle". It will shift any text within the rectangle over to the right, and insert a given string prefixing all the lines in the region. If comment-region didn't already exist, you could use this instead, for example. |
||
− | |||
− | <code>C-x r d</code> is "Delete Rectangle". It will delete the contents of the rectangle and move anything on the right over. |
||
− | |||
− | <code>C-x r r</code> is "Copy Rectangle to Register". It will prompt you for a register number so it can save it for later. |
||
− | |||
− | <code>C-x r g</code> is "Insert register". This will insert the contents of the given register, overwriting whatever happens to be within the target rectangle. (So make room) |
||
− | |||
− | <code>C-x r k</code> is "Kill rectangle". Delete rectangle and save contents for: |
||
− | |||
− | <code>C-x r y</code> is "Yank rectangle". This will insert the contents of |
||
− | the last killed rectangle. |
||
− | |||
− | As with all Emacs modifier combos, you can type <code>C-x r C-h</code> to find out what keys are bound beginning with the <code>C-x r</code> prefix. |
||
− | |||
− | == Aligning code == |
||
− | |||
− | Emacs22 has a neat tool called: align-regexp. Select a region you want to align text within, M-x align-regexp, and type a regexp representing the alignment delimiter. |
||
− | |||
− | For example, I often line up my Haddock comments: |
||
− | |||
− | <haskell> |
||
− | f :: a -- ^ does a |
||
− | -> Foo b -- ^ and b |
||
− | -> c -- ^ to c |
||
− | </haskell> |
||
− | |||
− | Select the region, and let the regexp be: <code>--</code> |
||
− | |||
− | <haskell> |
||
− | f :: a -- ^ does a |
||
− | -> Foo b -- ^ and b |
||
− | -> c -- ^ to c |
||
− | </haskell> |
||
− | |||
− | Of course, this works for just about anything. Personally, I've globally bound it to <code>C-x a r</code>: |
||
− | |||
− | <code>(global-set-key (kbd "C-x a r") 'align-regexp)</code>. |