如何让Emacs的magic-mode-alist匹配文件中间的字符串

6
我是一名使用OS X下Aquamacs的用户,其默认不将 .m 文件识别为 Objective-C 文件,而是将其视为 matlab 文件。从邮件列表中可以得知,这是因为维护者认为在将解决方案添加到发布版之前,他希望有一种清晰的方式来区分 Obj-C 文件和其他文件。
因此,我试图想出一个合适的 magic-mode-alist,以帮助正确识别 Objective-C 文件并切换到正确的模式。经过一番思考,似乎只需要检查三个关键字之一是否存在:
@implementation
@interface
@protocol

任何Objective-C文件都应该包含其中一个字符串,而它们也很可能不在Matlab文件中。
然后我尝试着想出一个magic-mode-alist变量来识别@implementation,我的第一次尝试是:
(add-to-list
 'magic-mode-alist
 '(".*^\@implementation.*" . objc-mode))

基本上 - 在文件开头的任何位置检查@implementation。

但是,当我将此代码放入我的.emacs文件中时,它似乎没有任何效果 - 打开一个包含@implementation的.m文件并没有切换到Obj-C模式。

有没有人知道我的magic-mode-alist条目存在什么问题?我找到的唯一的例子只是匹配文件开头的文本(用于nxml-mode),而不是文件中间的字符串。看起来我的正则表达式肯定有问题,但是注意到几个相同主题的变体都没有效果。

我在我的.emacs文件中有可工作的auto-mode-alist条目,可以选择正确的模式,因此我不需要任何关于如何做到这一点的建议,我想以“正确”的方式解决这个问题。

编辑:

感谢下面被接受的响应,以下是我在我的.emacs文件中最终使用的代码:

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

请注意,我在正则表达式中使用 "\n" 来代替 "^"(行的开头),因为准确确定类型非常重要 - 否则 .emacs 文件本身将因为其中包含了 @implementation 而进入 obj-c 模式。
需要注意的另一点是,magic-mode-alist 只会给定文件开头一定数量的字符来处理(由 magic-mode-regexp-match-limit 定义,默认为 4000 个字符),可能是出于性能方面的考虑。通常这足以找到 @implementation@interface 块的开始位置,但如果像一些人那样在文件头中插入修订注释,则可能需要大幅增加这个值。作为备份,我计划还包括使 .m 文件始终在 obj-mode 中打开的代码,因为我已经过了 Matlab 的日子 - 但希望这个 magic-mode 的更改至少可以进入 Aquamacs 的官方发行版,如果不能进入 Emacs 23 本身(为了实现这一点,可能需要进一步加强正则表达式)。
1个回答

7
在emacs中,正则表达式中的.不能匹配换行符。此外,^字符不是特殊字符(匹配行首),除非它是regexp中的第一个字符(根据手册的历史原因)。因此,你需要像这样做:
(add-to-list
 'magic-mode-alist
 '("\\(.\\|\n\\)*@implementation" . objc-mode))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接