Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Emacs magic-mode-alist to match against string in middle of file

I'm a user of Aquamacs under OS X, which by default does not recognize .m files as Objective-C but instead treats them as matlab files - from the mailing list, the reason for this is that it was felt by the maintainer that he wanted a clean way to distinguish Obj-C files from others before he added a solution into the distribution.

Thus, I was trying to come up with a proper magic-mode-alist that would help to properly identify Objective-C files and switch to the right mode - after some thought, it seemed like all I would nee to check for are the presence of one of three keywords:

@implementation
@interface
@protocol

Any Objectve-C file should have one of those strings in it, and they also would very likely not not be in a Matlab file.

I then tried coming up with a magic-mode-alist variant to recognize @implementation, my first try was:

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

Basically - check for @implementation anywhere in the file at the start of a line.

After putting this into my .emacs file though, it seemed to have no effect - opening a .m file with @implementation in it, did not switch to Obj-C mode.

Does anyone know what the issue might be with my magic-mode-alist entry? The only examples I could find just matched text at the very beginning of a file (for nxml-mode), and not for strings in the middle of a file. It seems like something must be wrong with my regex, but as noted a few variants of the same theme seemed to have no effect.

I have working entries in my .emacs file for auto-mode-alist to pull up the right mode today so I don't need any advice on how to do that, I'd like to solve this the "right" way.

EDIT:

Thanks to the accepted response below, here is the final code I have in my .Emacs file:

(setq magic-mode-alist
  (append (list  
       '("\\(.\\|\n\\)*\n@implementation" . objc-mode)
       '("\\(.\\|\n\\)*\n@interface" . objc-mode)
       '("\\(.\\|\n\\)*\n@protocol" . objc-mode))
      magic-mode-alist))

Note that I use "\n" as a replacement for "^" (beginning of line) in the regex, as it's important to accurately determine the type - otherwise the .emacs file itself would come up in obj-c mode just because @implementation was in there.

Something else to be aware of I came across researching this is that magic-mode-alist is only given a certain number of characters at the beginning of a file to work with (defined by magic-mode-regexp-match-limit, with default of 4000 characters), presumably for performance reasons. Normally that's more than enough to find the start of @implementation or @interface blocks, but if you insert revision comments in the headers of files as some people do, you may need to increase this substantially. Just as a backup, I plan to also include the code that makes .m files always open in obj-mode using auto-mode-alist, since my Matlab days are far behind me - but hopefully this magic-mode change can go into the official distribution of Aquamacs at least, if not Emacs 23 itself (the regexs probably should be beefed up a little more for that to happen).

like image 272
Kendall Helmstetter Gelner Avatar asked Aug 13 '09 22:08

Kendall Helmstetter Gelner


1 Answers

In emacs regular expressions, . does not match newlines. Also, the ^ character is not special (matching beginning of line) unless it's the first character in the regexp (for historical reasons, according to the manual).

So you need something like:

(add-to-list
 'magic-mode-alist
 '("\\(.\\|\n\\)*@implementation" . objc-mode))
like image 193
Trey Jackson Avatar answered Nov 12 '22 12:11

Trey Jackson