tags:

views:

776

answers:

4

I edit my StackOverflow answers and questions with ViewSourceWith and Emacs. Often, I include code and StackOverflow formatting rules say that it must be indented by four spaces to be recognized as such. Doing it by hand or even with macros is painful.

I searched in SO's previous postings but found nothing.

Starting from the Python mode, I wrote:

(defun text-shift-region (start end count)
  "Indent lines from START to END by COUNT spaces."
  (save-excursion
(goto-char end)
(beginning-of-line)
(setq end (point))
(goto-char start)
(beginning-of-line)
(setq start (point))
(indent-rigidly start end count)))

(defun text-shift-region-right (start end &optional count)
  "Shift region of code to the right
   Stolen from python-mode.
   The lines from the line containing the start of the current region up
   to (but not including) the line containing the end of the region are
   shifted to the right, by `text-indent-offset' columns.

   If a prefix argument is given, the region is instead shifted by that
   many columns.  With no active region, indent only the current line."
  (interactive
   (let ((p (point))
     (m (mark))
     (arg current-prefix-arg))
 (if m
     (list (min p m) (max p m) arg)
   (list p (save-excursion (forward-line 1) (point)) arg))))
  (text-shift-region start end (prefix-numeric-value
     (or count text-indent-offset)))
  )

;; Code in StackOverflow must be marked by four spaces at the
;; beginning of the line
(setq text-indent-offset 4)
(global-set-key "\C-c>" 'text-shift-region-right)

It seems to work but I welcome advices, alternatives, bug reports, etc.

+8  A: 

C-x TAB runs indent-rigidly. Given a numerical argument of four it will do what you want. Alternatively use <pre><code> to introduce your code (see the first paragraph of Markdown Editing Help).

Edit: your interactive declaration would better be written:

(interactive "r
p")
kmkaplan
C-x TAB requires the region to be marked. The Python-mode code, which I stole, works on the region, if there is one, or else on the current line.
bortzmeyer
You mean active. Normally indenting a single line by 4 does not really warrant a specific binding. C-a SPACE SPACE SPACE SPACE.
kmkaplan
Well, I still prefer my method but these two solutions are nice too. Accepted.
bortzmeyer
+1  A: 

Your code looks fine to me. I think the re-setting of end in text-shift-region is not necessary, but other than that, it looks fine.

Joe Casadonte
+4  A: 

Another easy way to do is to use emacs's powerful rectangular editing ability: set your region starting from the beginning of the first line and ending at the beginning of the last line you want to indent (note: the it has to be in the beginning of the line since you don't want to replace your existent text!), then do

C-x r t (string-rectangle)

Then just enter 4 spaces as prompted. Voila! No extra lisp hacking needed. This additionally gives you flexibility to insert other stuff beside spaces to the beginning or anywhere middle of a bunch of lines.

polyglot
An even simpler command is C-x r o, open-rectangle, assuming that either the first or the last line of the region is at least four characters long: position either end of the region four characters into the line and the other one at the beginning of the line, and type C-x r o.
Jouni K. Seppänen
+4  A: 

Using C-x TAB to indent-rigidly (as mentioned in another answer) is the easiest way. Simply mark the region you want to indent and press C-u C-x TAB. As the default prefix for C-u is 4, this should do exactly what you want.

Juan Garcia