views:

137

answers:

3

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)
+2  A: 

Your defaults are possibly being overridden by cc-mode's style feature.

Try initialising the default style like this:

(setq c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "user")))

You should be able to paste the preceding line into your .emacs file, or customize the c-default-style variable. The default has (other "gnu") as the last element of the list, which means that all non-Java and non-awk files get the gnu style instead of what you set with setq. The special user style gets initialised from your manually-set style variables.

Another option is to pick one of the built-in styles instead of defining it yourself, or to create your own style using the c-add-style function. To do this, change "user" in the above command to the name of the style (as a string). Try the the stroustrup or python built-in styles to format if-statements how you want.

Doug
I tried to insert the line you wrote and load-file, but I still see the gnu standard.I also tried with "stroustrup" and "python", no difference.
Gauthier
Do you have a customize file that's being loaded and overriding your settings? Also, I'm not sure about using setq-default with the user style variables - can you try plain setq? (That doesn't explain why stroustrup/python wouldn't work, though.)
Doug
I don't think so. I added my whole .emacs in the original post, I think it might help.With "user" I nearly get what I want. Tabs are not replaced by spaces, I don't get why.
Gauthier
setq instead of setq-default made no difference.
Gauthier
Gauthier
+4  A: 

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.

Steven Huwig
Gauthier
I kept modifying my .emacs and running `M-x load-file` `~/.emacs.d/init.el`, and not seeing the effects of my changes. Apparently, the changes in my init file were *not* applied to buffers that were already open!Now I reopen a buffer after the load-file and I am a bit less confused.
Gauthier
yap. When changing my init.el file, usually I keep one instance of emacs open to edit the init.el file, and then open and close another instance to test the changes.
Cheeso
+2  A: 

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

Cheeso
Gauthier
Cheeso