title: Tab and Shift-Tab smart indent on selected text
body: <p>It's standard in most modern editors that you can highlight a piece of code and indent or unindent a tab or however many spaces you're using; how do you do this in emacs?</p>
  
  <p>So, for example I just opened sublime text, highlighted the following piece of code:</p>
  
  <pre class="lang-haskell prettyprint-override"><code>variation1 person phoneMap carrierMap addressMap =
      case M.lookup person phoneMap of
        Nothing -&gt; Nothing
        Just number -&gt;
            case M.lookup number carrierMap of
              Nothing -&gt; Nothing
              Just carrier -&gt; M.lookup carrier addressMap
  </code></pre>
  
  <p>then pressed tab and got</p>
  
  <pre class="lang-haskell prettyprint-override"><code>  variation1 person phoneMap carrierMap addressMap =
        case M.lookup person phoneMap of
          Nothing -&gt; Nothing
          Just number -&gt;
              case M.lookup number carrierMap of
                Nothing -&gt; Nothing
                Just carrier -&gt; M.lookup carrier addressMap
  </code></pre>
  
  <p>one shift-tab on that code returns it back to where it was, and if I continuing pressing shift-tab I eventually get the following:</p>
  
  <pre class="lang-haskell prettyprint-override"><code>variation1 person phoneMap carrierMap addressMap =
  case M.lookup person phoneMap of
  Nothing -&gt; Nothing
  Just number -&gt;
  case M.lookup number carrierMap of
  Nothing -&gt; Nothing
  Just carrier -&gt; M.lookup carrier addressMap
  </code></pre>
  
  <p>Quote from another response:</p>
  
  <blockquote>
    <p>emacs language modes don't really have a notion of 'indent this block
    1 tab further'. Instead they're very opinionated and have a notion of
    'this is the correct indentation' and that's what you get when you hit
    tab in a language mode.</p>
  </blockquote>
  
  <p>Except when I do that with the following code (haskell mode and ghc mod enabled):</p>
  
  <pre class="lang-haskell prettyprint-override"><code>import Monad
  import System
  import IO
  import Random
  import Control.Monad.State
  
  type RandomState a = State StdGen a
  data CountedRandom = CountedRandom {
        crGen :: StdGen
      , crCount :: Int
      }
  
  type CRState = State CountedRandom
  
  getRandom :: Random a =&gt; RandomState a
  getRandom =
    get &gt;&gt;= \gen -&gt;
    let (val, gen') = random gen in
    put gen' &gt;&gt;
    return val  
  </code></pre>
  
  <p>I get the following:</p>
  
  <pre class="lang-haskell prettyprint-override"><code>import Monad
    import System
    import IO
    import Random
    import Control.Monad.State
  
  type RandomState a = State StdGen a
  data CountedRandom = CountedRandom {
    crGen :: StdGen
    , crCount :: Int
    }
  
  type CRState = State CountedRandom
  
                 getRandom :: Random a =&gt; RandomState a
                 getRandom =
    get &gt;&gt;= \gen -&gt;
    let (val, gen') = random gen in
    put gen' &gt;&gt;
    return val  
  </code></pre>
  
  <p>when I wanted</p>
  
  <pre class="lang-haskell prettyprint-override"><code>import Monad
  import System
  import IO
  import Random
  import Control.Monad.State
  
  type RandomState a = State StdGen a
  data CountedRandom = CountedRandom {
        crGen :: StdGen
      , crCount :: Int
      }
  
  type CRState = State CountedRandom
  
  getRandom :: Random a =&gt; RandomState a
  getRandom =
    get &gt;&gt;= \gen -&gt;
      let (val, gen') = random gen in
      put gen' &gt;&gt;
      return val  
  </code></pre>
  
  <hr>
  
  <p>Near enough to a solution from ataylor:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>(defcustom tab-shift-width 4
    "Sets selected text shift width on tab"
    :type 'integer)
  (make-variable-buffer-local 'tab-shift-width)
  
  (global-set-key 
   (kbd "&lt;tab&gt;")
   (lambda (start end)
     (interactive "r")
     (if (use-region-p)
         (save-excursion
       (let ((deactivate-mark nil))
         (indent-rigidly start end tab-shift-width)))
       (indent-for-tab-command))))
  
  (global-set-key 
   (kbd "S-&lt;tab&gt;")
   (lambda (start end)
     (interactive "r")
     (if (use-region-p)
         (save-excursion
       (let ((deactivate-mark nil))
         (indent-rigidly start end (- tab-shift-width))))
       (indent-for-tab-command))))
  </code></pre>
  
  <p>It'd be nice if emacs had support for indent detection (i.e., just grab the value of some variable); the closest thing I found to this was a plugin called dtrt indent but it doesn't work for Haskell.</p>