サイトマップ 更新履歴 ニュース Elispセクション 利用手引

CcMode

Last edit

Summary: Moved material to ObjectiveCMode

Changed:

< == Modes provided by CC Mode ==

to

> Modes provided by CC Mode:

Changed:

< * CPlusPlusMode -- (real name C++ mode)

to

> * CPlusPlusMode -- C++ mode

Changed:

< * Objective-C Mode

to

> * ObjectiveCMode

Changed:

< == Extensions to CC Mode ==

to

> Extensions to CC Mode:

Changed:

< == Using different styles according to source location ==

to

> * CCLookup - Searching CPP Reference (Documentation)
> ** http://github.com/tsgates/cclookup/tree/master
> ** http://taesoo.org/Opensource/CClookup

> Using different styles according to source location:

Changed:

< == Key bindings ==
< * CCModeKeyBinding
< ==
Refactoring C code ==

to

> Refactoring C code:

Deleted:

< ;; move current function up

Added:

> "Move current function up."

Changed:

< (kill-region (region-beginning) (region-end))
< (c-beginning-of-defun 1)
< (yank)))
< ;; move current function down

to

> (let ((fun-beg (point))
> (fun-end (mark)))
> (transpose-regions (progn
> (c
-beginning-of-defun 1)
> (point))
> (progn
> (
c-end-of-defun 1)
> (point))
> fun-beg fun-end))))

Added:

> "Move current function down."

Changed:

< (save-excursion

to

> (save-excursion

Changed:

< (kill-region (region-beginning) (region-end))
< (c-beginning-of-defun -1)
< (yank)))

to

> (let ((fun-beg (point))
> (fun
-end (mark)))
> (transpose-regions fun-beg fun-end
> (progn
> (c-beginning-of-defun -1)
> (point))
> (progn
> (c-end-of-defun 1)
> (point))))))

Deleted:

< Your comments are welcome.
< --dfa
< Probably you you can use `delete-and-extract-region' instead of `kill-region' plus `yank'.
< --ttn

Deleted:

< == CCLookup: Searching CPP Reference (Documentation) ==
< * github: http://github.com/tsgates/cclookup/tree/master
< * web: http://taesoo.org/Opensource/CClookup
< == Objective C++ ==
< Emacs doesn't know about Objective C++. If you open a ".mm" file, it'll be in text-mode or lisp-mode or whatever your default is, which is not very useful.
< Unfortunately, until someone writes an objc++-mode, you have to choose between objc-mode and c++-mode. Either one is going to have incomplete syntax highlighting, but the latter also often gets confused with indentation. So, add something like this to your .emacs to open ".mm" files as objc-mode:
< <pre>
< (add-to-list 'auto-mode-alist '("\\.mm\\'" . objc-mode))
< </pre>
< === Objective C headers ===
< The default mode for .h files is c-mode. This works reasonably well for C++ headers, although it has incomplete syntax highlighting, but it's much worse for Objective C, where you get things like parameters not lining up properly by their colons. You can handle this by adding a function to magic-mode-alist, like this:
< <pre>
< (add-to-list 'magic-mode-alist
< `(,(lambda ()
< (and (string= (file-name-extension buffer-file-name) "h")
< (re-search-forward "@\\<interface\\>"
< magic-mode-regexp-match-limit t)))
< . objc-mode))
< </pre>
< So, any .h file that defines an @interface is objc-mode instead of c-mode. (You could extend this to distinguish C++ from C by looking for class or template definitions, but I haven't bothered.)
< === ff-find-other-file and friends ===
< find-file-other-file doesn't work right, for two reasons.
< The first problem is that cc-other-file-alist doesn't know about Obj-C++ (.mm) files, and doesn't know that .h files can be headers for .m and .mm files. To fix that:
< <pre>
< (require 'cl) ;; for the extended "push" macro
< (require 'find-file) ;; for the "cc-other-file-alist" variable
< (push ".m" (cadr (assoc "\\.h\\'" cc-other-file-alist)))
< (push ".mm" (cadr (assoc "\\.h\\'" cc-other-file-alist)))
< (push '("\\.m\\'" (".h")) cc-other-file-alist)
< (push '("\\.mm\\'" (".h")) cc-other-file-alist)
< </pre>
< The bigger problem is that the header-search algorithm doesn't understand frameworks. So, &lt;sys/types&gt; properly finds /usr/include/sys/types, but &lt;Foundation/Foundation.h&gt; fails. To fix that:
< <pre>
< (defadvice ff-get-file-name (around ff-get-file-name-framework
< (search-dirs
< fname-stub
< &optional suffix-list))
< "Search for Mac framework headers as well as POSIX headers."
< (or
< (if (string-match "\\(.*?\\)/\\(.*\\)" fname-stub)
< (let* ((framework (match-string 1 fname-stub))
< (header (match-string 2 fname-stub))
< (fname-stub (concat framework ".framework/Headers/" header)))
< ad-do-it))
< ad-do-it))
< (ad-enable-advice 'ff-get-file-name 'around 'ff-get-file-name-framework)
< (ad-activate 'ff-get-file-name)
< </pre>
< Unfortunately, there are some libraries that effectively reimplement parts of find-file.el instead of using it, which means you may need to patch more functions if you use those libraries.
< Of course you'll also want to add the framework paths to cc-search-directories. I used to have code to extract the gcc defaults for both include directories and framework directories at startup, but that turns out to be not much better than using the built-in defaults, because it doesn't take into account the local values for the project(s) I work on. So now I just hard-code it in my .emacs, and then have project-specific files to eval as needed.
< <pre>
< (setq cc-search-directories '("." "../include" "/usr/include" "/usr/local/include/*"
< "/System/Library/Frameworks" "/Library/Frameworks"))
< </pre>


CC Mode is a powerful package that provides modes for editing C and C-like (C++, Java, Objective C, CORBA IDL, etc.) files. For much more information (including an InfoMode manual), see the CC Mode homepage:

Modes provided by CC Mode:

Extensions to CC Mode:

Using different styles according to source location:

This could probably do with some modifications to support more than one style type. C++ code is also not affected.

  (setq my-linux-style-path-alist (list (expand-file-name
                               "~/src/version_control/sexy")))
  (add-hook 'c-mode-hook (lambda ()
                           (dolist (path my-linux-style-path-alist)
                             (if (string-match path (buffer-file-name))
                                 (c-set-style "linux")))))

I do it like:

(setq artm-c-styles-alist
      '(("/projects/vlc" . "vlc")
	(nil . "linux")))

(defun artm-guess-c-style ()
  (let ((style
	 (assoc-default buffer-file-name artm-c-styles-alist
			(lambda (pattern path)
			  (or (not pattern)
			      (and (stringp path)
				   (string-match pattern path))))
			;; factory default (in case you forget
			;; to add (nil . "some style") to
			;; artm-c-styles-alist
			'(nil . "linux"))))
    (cond
     ((stringp style) (c-set-style style))
     ((functionp style) (style)))))

(add-hook 
 'c-mode-hook 'artm-guess-c-style)

Refactoring C code:

(defun my-move-function-up ()
  "Move current function up."
  (interactive)
  (save-excursion
    (c-mark-function)
    (let ((fun-beg (point))
          (fun-end (mark)))
      (transpose-regions (progn
                           (c-beginning-of-defun 1)
                           (point))
                         (progn
                           (c-end-of-defun 1)
                           (point))
                         fun-beg fun-end))))

(defun my-move-function-down ()
  "Move current function down."
  (interactive)
  (save-excursion
    (c-mark-function)
    (let ((fun-beg (point))
          (fun-end (mark)))
      (transpose-regions fun-beg fun-end
                         (progn
                           (c-beginning-of-defun -1)
                           (point))
                         (progn
                           (c-end-of-defun 1)
                           (point))))))
(defun mark-c-scope-beg ()
  "Marks the c-scope (region between {}) enclosing the point. 
   Naive, as will be confused by { } within strings"
  (let 
	  ((scope-depth 1))
	(while (not (= scope-depth 0))
	  (search-backward-regexp "}\\|{")
	  (if (string= (char-to-string (char-before)) "}")
		  (setq scope-depth (1+ scope-depth))
			(setq scope-depth (1- scope-depth)))))
  (point))

(defun mark-c-scope-end ()
  "Marks the c-scope (region between {}) enclosing the point. 
   Naive, as will be confused by { } within strings"
  (let 
	  ((scope-depth 1))
	(while (not (= scope-depth 0))
	  (search-forward-regexp "}\\|{")
	  (if (string= (char-to-string (char-before)) "}")
		  (setq scope-depth (1- scope-depth))
			(setq scope-depth (1_ scope-depth)))))
  (point))

(defun kill-c-scope ()
  (interactive)
  (let
	  ((inital-point (point)))
	(save-excursion 
	  (let
		((beg (mark-c-scope-beg)))
		(goto-char inital-point)
		(let ((end (mark-c-scope-end))))))))

There must be a better way to do this…

There are c-beginning-of-defun and c-end-of-defun, plus c-mark-function in cc-cmds.el – that might be it!


CategoryProgramming CategoryModes