Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs indentation difficulty

I'm really trying to switch to emacs, but learning to setup the environment is a real pain. Everybody says it's worth it, so I just continue.

I want my c code to be implemented that way:

if(asdf)
{
    asdr = 1;
}

Depending on the current standard (I know, don't get me started), could be:

if(asdf) {
    asdr = 1;
}

I can't seem to change the indentation size from 2, it always looks like the GNU standard:

if(asdf)
  {
    asdr = 1;
  }

, which I dislike. Here is what I have put in my .emacs:

; Warn in C for while();, if(x=0), ...
(global-cwarn-mode 1)

; no electric mode in c
(c-toggle-electric-state -1)
; indent the current line only if the cursor is at the beginning of the line
(setq-default c-tab-always-indent nil)
(setq-default c-indent-level 4)
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)
(setq-default c-basic-offset 4)
(setq-default c-basic-indent 4)
; These commands I read about on the web, but they don't work?
;(highlight-tabs)
;(highlight-trailing_whitespace)

This did not help, I have still the GNU indent. Anyone?

--- EDIT TO ADD MY WHOLE .emacs (actually ~/.emacs.d/init.el)

; directory to put various el files into
(add-to-list 'load-path "C:/Program/emacs-22.3/includes")

; loads ruby mode when a .rb file is opened.
(autoload 'ruby-mode "ruby-mode" "Major mode for editing ruby scripts." t)
(setq auto-mode-alist  (cons '(".rb$" . ruby-mode) auto-mode-alist))
(setq auto-mode-alist  (cons '(".rhtml$" . html-mode) auto-mode-alist))

(add-hook 'ruby-mode-hook
          (lambda()
            (add-hook 'local-write-file-hooks
                      '(lambda()
                         (save-excursion
                           (untabify (point-min) (point-max))
                           (delete-trailing-whitespace)
                           )))
            (set (make-local-variable 'indent-tabs-mode) 'nil)
            (set (make-local-variable 'tab-width) 2)
            (imenu-add-to-menubar "IMENU")
            (define-key ruby-mode-map "\C-m" 'newline-and-indent) ;Not sure if this line is 100% right but it works!
            (require 'ruby-electric)
            (ruby-electric-mode t)
            ))

; Install mode-compile to give friendlier compiling support!
(autoload 'mode-compile "mode-compile"
   "Command to compile current buffer file based on the major mode" t)
(global-set-key "\C-cc" 'mode-compile)
(autoload 'mode-compile-kill "mode-compile"
 "Command to kill a compilation launched by `mode-compile'" t)
(global-set-key "\C-ck" 'mode-compile-kill)


(show-paren-mode 1)

; Color theme
(require 'color-theme)
(color-theme-pok-wog)
;;Emacs.pane.menubar.* does not seem to work? 
;Emacs.pane.menubar.background: darkGrey
;Emacs.pane.menubar.foreground: black


; Default font 9 pt
(set-face-attribute 'default nil :height 80)

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 )
(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(font-lock-comment-face ((t (:foreground "limegreen" :slant oblique))))
 '(font-lock-preprocessor-face ((t (:inherit font-lock-builtin-face :foreground "orange" :weight bold)))))


(global-set-key [C-tab] 'other-window)
(global-set-key [C-S-tab] (lambda () (interactive) (other-window -1)))

(defun linux-c-mode ()
  "C mode with adjusted defaults for use with the Linux 
kernel."
  (interactive)
  (c-mode)
  (setq c-indent-level 8)
  (setq c-brace-imaginary-offset 0)
  (setq c-brace-offset -8)
  (setq c-argdecl-indent 8)
  (setq c-label-offset -8)
  (setq c-continued-statement-offset 8)
  (setq indent-tabs-mode nil)
  (setq tab-width 8))


; Warn in C for while();, if(x=0), ...
(global-cwarn-mode 1)

; no electric mode in c
(c-toggle-electric-state -1)
; indent the current line only if the cursor is at the beginning of the line
(setq-default c-tab-always-indent nil)
(setq-default c-indent-level 4)
(setq-default tab-width 4)
(setq indent-tabs-mode nil)
(setq-default c-basic-offset 4)
(setq-default c-basic-indent 4)
; These commands I read about on the web, but they don't work?
;(highlight-tabs)
;(highlight-trailing_whitespace)
(setq indent-tabs-mode nil)
(setq c-default-style "user")


;; Remove lull: scroll bar, tool bar, menu bar.
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))


;; restore window size as it was at previous use
(defun restore-saved-window-size()
  (unless (load "~/.emacs.d/whsettings" t nil t)
    (setq saved-window-size '(80 30)))
  (nconc default-frame-alist `((width . ,(car saved-window-size))
                   (height . ,(cadr saved-window-size)))))

(restore-saved-window-size)

(defun save-window-size-if-changed (&optional unused)
  (let ((original-window-size  `(,(frame-width) ,(frame-height))))
    (unless (equal original-window-size saved-window-size)
      (with-temp-buffer
        (setq saved-window-size original-window-size) 
        (insert (concat "(setq saved-window-size '"
                        (prin1-to-string saved-window-size) ")"))
        (write-file "~/.emacs.d/whsettings")))))

(add-hook 'window-size-change-functions 'save-window-size-if-changed)

;; Ack as a replacment for grep
(global-set-key "\M-s" 'ack)
(require 'ack)
like image 211
Gauthier Avatar asked Mar 17 '10 11:03

Gauthier


2 Answers

The EmacsWiki has a nice article on IndentingC.

In fact, EmacsWiki has nice articles on everything. I wouldn't want to have learned Emacs before it existed.

like image 126
Steven Huwig Avatar answered Oct 05 '22 23:10

Steven Huwig


Indenting in emacs cc-mode is governed by a set of offsets, each of which can be set, according to a name attached to the offset.

The open-curly after an if statement has an offset, with a name. If you change the offset value, the open-curly will be indented differently. Likewise, the open-curly after a function declaration, has a named offset. Line continuations in a macro have a named offset. Case labels in a switch statement, do while loops. They all have offsets. There are a zillion of 'em, all stored in a variable called c-offsets-alist.

The styles mentioned in other places provide a "basic offset", which is normally 2, 4, or 8 spaces, and then a value for c-offsets-alist. Each style also has a name, and you can derive custom styles from other styles. Like this:

(c-add-style "myCStyle"
  '("bsd"  ; this must be defined elsewhere - it is in cc-modes.el
  (c-basic-offset . 4)
  (c-echo-syntactic-information-p . t)
  (c-comment-only-line-offset . (0 . 0))
  (c-offsets-alist . (
    (c                     . c-lineup-C-comments)
    (statement-case-open   . 0)
    (case-label            . +)
    (substatement-open     . 0)
    ))
  ))

The value for each named offset in c-offsets-alist is one of:

  • 0 implying, keep the indent the same as the previous line
  • + implying, increase the indent, one additional level
  • - implying, decrease the indent, one additional level

You can also use ++, --, and so on. Put something like that, to define a style, in your .emacs file. Then, to automatically employ that style when editing C files, use c-set=style in a c-mode hook, like this:

(defun doug-c-mode-hook-fn ()
  (cond (window-system
     ;; use my defined style for all C modules
     (c-set-style "myCStyle")
     ;; never convert leading spaces to tabs
     (setq indent-tabs-mode nil)
       ....
  )))

(add-hook 'c-mode-hook 'doug-c-mode-hook-fn)

The next question is, how does one determine which of the named c-offsets you need to set for any particular situation? There's an app for that. ok, not an app, but a elisp function.

M-x c-set-offset
Displays where emacs thinks it is, syntactically, in a cc-mode source file. To use it, place the cursor at the position where you'd like to learn the offset name, or change the offset. Then invoke this function. It will tell you the name of the offset for the current syntactical element.
If you change the value of that named element in your c-offsets-alist for your chosen style, something that is typically done in .emacs or your equivalent, then the indent setting will be true for all source modules.

alt text

like image 28
Cheeso Avatar answered Oct 06 '22 00:10

Cheeso