12

My team uses a special type of file for configuration, and I would like to auto-indent (block indent) the file using emacs.

I would like to increase the indentation by a tab size for an opening parenthesis - { or [, and decrease by a tab size for a closing parenthesis - } or ] .

For example,

files = {
    file1 = first_file.txt
    file2 = second_file.txt
    rules = { 
        skip_header = 1
        fast_process = 1
    }
}

C-style indentation doesn't work since a line doesn't end with semi-colon.

I have studied about emacs indentation for half a day today, but still doesn't know how to do this.

canonv
  • 121
  • 1
  • 4

2 Answers2

17

Derive a new mode from text-mode or something and create your own indentation function. I know it's easier said than done, so this might be close enough:

(define-derived-mode foo-mode text-mode "Foo"
  "Mode for editing some kind of config files."
  (make-local-variable 'foo-indent-offset)
  (set (make-local-variable 'indent-line-function) 'foo-indent-line))

(defvar foo-indent-offset 4
  "*Indentation offset for `foo-mode'.")

(defun foo-indent-line ()
  "Indent current line for `foo-mode'."
  (interactive)
  (let ((indent-col 0))
    (save-excursion
      (beginning-of-line)
      (condition-case nil
          (while t
            (backward-up-list 1)
            (when (looking-at "[[{]")
              (setq indent-col (+ indent-col foo-indent-offset))))
        (error nil)))
    (save-excursion
      (back-to-indentation)
      (when (and (looking-at "[]}]") (>= indent-col foo-indent-offset))
        (setq indent-col (- indent-col foo-indent-offset))))
    (indent-line-to indent-col)))

Open your file and do M-x foo-mode

scottfrazer
  • 17,079
  • 4
  • 51
  • 49
  • 1
    Thank you Scottfrazer. It works near perfect. However, it adds four spaces for single indentation and add one tab instead of eight spaces for double indentation. When the file was open in my collegues vi, the indentation is not pretty any more. Can you tell me how to make it add one tab per one indentation? If that is not possible, 4 spaces per indentation is also fine. – canonv Nov 11 '10 at 21:04
  • 1
    It sounds like a basic indentation setup issue not related to my answer. Try putting `(setq-default indent-tabs-mode nil)` in your .emacs file if you want no tabs, or `(setq foo-indent-offset tab-width)` if you want all tabs. – scottfrazer Nov 12 '10 at 14:08
0

It looks to me as though javascript-mode would do the right thing with your sample. It might not be perfect, but a lot easier than writing your own indentation mode.

Gareth Rees
  • 64,967
  • 9
  • 133
  • 163
  • Is javascript-mode same as java-mode? I can't find javascript-mode from M-x commands. – canonv Nov 11 '10 at 19:13
  • java-mode works well for a parentheses, but doesn't work well for brackets. Can I make an adjustment on java-mode so that it can work for brackets? – canonv Nov 11 '10 at 19:21
  • `javascript-mode` (an alias for `js-mode`) comes built in to Emacs 23.2. Maybe you're running an old version of Emacs? If you can't or won't upgrade, see [JavaScriptMode](http://www.emacswiki.org/emacs/JavaScriptMode) on the Emacs wiki. – Gareth Rees Nov 11 '10 at 19:23
  • My version is 22.2. This is for my company server, and it may take a few weeks to upgrade even if they are willing to do. – canonv Nov 11 '10 at 19:31