[OS X Emacs] Changing magic-mode-alist for Objective-C files - keyword suggestions

Kendall Gelner kendall.gelner at kigisoftware.com
Thu Jul 30 18:26:45 EDT 2009


I've been using Aquamacs for a while for causal use, but with the  
preview release of 23 I've been thinking about using it more day to  
day in development workflow.

I've long wondered why the default for .m files is Matlab instead of  
objc-mode.  For a while now I've had the following added to my .emacs  
file:

(setq auto-mode-alist (cons '("\\.m$" . objc-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.h$" . objc-mode) auto-mode-alist))

But I figured there was a deeper reason why something like this was  
not the default after many revisions.  So I wandered through the  
mailing list archive, and  came across this message thread:

http://email.esm.psu.edu/pipermail/macosx-emacs/2009-January/001147.html

Which ended with:
--------
The right way to distinguish MATLAB from ObjC files would be via
`magic-mode-alist'.  That said, I don't see how to reliably identify
either file type.  I guess, ObjC files commonly have some comments /*
*/ or #include statements.
--------

Now first of all, I would say that I've felt a variant of emacs  
targeting OS X should by default load .m files in objc-mode.  After  
all, there are going to be a lot more people programming cocoa than  
Matlab (which I have used in the past, so I'm aware of what it is  
for).  But then it opens up the much more ambiguous question,  
should .h files come up in objc-mode by default?  In that case I would  
think it far less likely that someone using emacs would be editing  
Objective-C code than more standard C or C++ files just due to objc- 
users more likely using XCode.  But that leaves a very weird  
discrepancy in editing behavior, and so I guess we are at the current  
position...

But I would like to help, and I do think there are keywords you could  
latch onto that would help magic-mode-alist more correctly come up  
with the right result.  I believe the keywords to use would be:

.h files:
	@interface (would generally come with a paired .m file as well)
                  or
	@protocol  (in this case there is a .h file but no .m file)

.m files
	@implementation

These are pretty much always going to be present in the corresponding  
objective-C files (.h or .m).

Based on this, I tried a simple magic-mode-alist :

(add-to-list
  'magic-mode-alist
  '(".*^\@implementation.*" . objc-mode))

But this did not seem to work, instead the objective-C files open in  
fundamental mode.   Can anyone help with improving my syntax for using  
magic-mode-alist?   The only example I could find was for nxml mode,  
matching a string at the very start of the file (which none of the  
three objc strings would be, as @implementation and the others are in  
the middle).  Then it could be a useful default for Aquamacs  
thereafter....

At the very end of this email, I've included samples of a .m, a .h,  
and a protocol .h file that are representative of what one might find  
in an objective-C file in case anyone wants to test an alternate magic- 
mode-alist fix.  Immediately below is a richer .emacs configuration  
example I found to set defaults for opening .m and .h files correctly  
so that any list readers can get this set up correctly right away -  
though I agree with the sentiment that magic-mode-alist is the right  
way to fix this good and that's why I'd like my example above repaired.

Thanks in advance for any help!

----------------

;;
;; ===== Some basic XCode Integration =====
;;
(setq auto-mode-alist
       (cons '("\\.m$" . objc-mode) auto-mode-alist))
(setq auto-mode-alist
       (cons '("\\.mm$" . objc-mode) auto-mode-alist))

;;
;; ===== Opening header files =====
;; Allows to choose between objc-mode, c++-mode and c-mode
(defun bh-choose-header-mode ()
   (interactive)
   (if (string-equal (substring (buffer-file-name) -2) ".h")
       (progn
         ;; OK, we got a .h file, if a .m file exists we'll assume it's
         ; an objective c file. Otherwise, we'll look for a .cpp file.
	; if there's no matching .m or .cpp, then we assume objc as it might  
be a protocol.
         (let ((dot-m-file (concat (substring (buffer-file-name) 0 -1)  
"m"))
               (dot-cpp-file (concat (substring (buffer-file-name) 0  
-1) "cpp")))
           (if (file-exists-p dot-m-file)
               (progn
                 (objc-mode)
                 )
             (if (file-exists-p dot-cpp-file)
                 (c++-mode)
                 (objc-mode)
               )
	
             )
           )
         )
     )
   )

(add-hook 'find-file-hook 'bh-choose-header-mode)

----------------

Example Files


----------------  .m file ----------------

//
//  MyObjcFile.m
//
//  Created by Kendall Gelner on 7/30/09.
//  Copyright 2009 KiGi Software. All rights reserved.
//

#import "MyObjcFile.h"


@implementation MyObjcFile

@end

----------------  .h file ----------------

//
//  MyObjcFile.h
//
//  Created by Kendall Gelner on 7/30/09.
//  Copyright 2009 KiGi Software. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface MyObjcFile : NSObject {

}

@end


----------------  .h protocol file ----------------
//
//  MyProtocol.h
//
//  Created by Kendall Gelner on 7/30/09.
//  Copyright 2009 KiGi Software. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@protocol MyProtocol


@end




More information about the MacOSX-Emacs mailing list