How to get Emacs magic-mode-alist to match against string in middle of file
emacs, objective-c
Solution
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))
Problem
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).