Emacs 主要模式 - 关键字"special char"和"one char"关键字



我想为emacs编写一个主要模式,它应该为mml(音乐宏语言(关键字进行语法高亮显示。我遵循了本教程:http://ergoemacs.org/emacs/elisp_syntax_coloring.html

这是我当前的代码(在x事件下仍然有占位符,x函数我还没有调整,并从教程中接管(:

;; 
;; to install this mode, put the following lines
;;     (add-to-list 'load-path "~/.emacs.d/lisp/")
;;     (load "mml-mode.el")
;; into your init.el file and activate it with
;; ALT+X mml-mode RET
;; 
;; create the list for font-lock.
;; each category of keyword is given a particular face
(setq mml-font-lock-keywords
(let* (
;; define several category of keywords
(x-keywords '("#author" "#title" "#game" "#comment"))
(x-types '("&" "?" "/" "=" "[" "]" "^" "<" ">"))
(x-constants '("w" "t" "o" "@" "v" "y" "h" "q" "p" "n" "*" "!"))
(x-events '("@" "@@" "ooo" "oooo"))
(x-functions '("llAbs" "llAcos" "llAddToLandBanList" 
"llAddToLandPassList"))
;; generate regex string for each category of keywords
(x-keywords-regexp (regexp-opt x-keywords 'words))
(x-types-regexp (regexp-opt x-types 'words))
(x-constants-regexp (regexp-opt x-constants 'words))
(x-events-regexp (regexp-opt x-events 'words))
(x-functions-regexp (regexp-opt x-functions 'words)))
`(
(,x-types-regexp . font-lock-type-face)
(,x-constants-regexp . font-lock-constant-face)
(,x-events-regexp . font-lock-builtin-face)
(,x-functions-regexp . font-lock-function-name-face)
(,x-keywords-regexp . font-lock-keyword-face)
)))
;;;###autoload
(define-derived-mode mml-mode text-mode "mml mode"
"Major mode for editing mml (Music Macro Language)"
;; code for syntax highlighting
(setq font-lock-defaults '((mml-font-lock-keywords))))
;; add the mode to the `features' list
(provide 'mml-mode)

但现在有两个问题:首先,我有几个以#(例如#author(开头的关键字。但#似乎不起作用,因为如果我不考虑它,它就会起作用。

(x-keywords '("#author"))不起作用。

(x-keywords '("author"))工作,但#未着色。@也会出现同样的问题。可能也会和其他人一起工作,但我会努力让他们一个接一个地工作。

其次,一个关键词似乎至少需要两个字母。

(x-keywords '("o"))不起作用。

(x-keywords '("oo"))作品

但我有几个";关键字";后面只有一个字母和两个(任意(十六进制数(0-F((例如o7D(如何指定找到这些一个字母的关键字?(最好与数字一起使用,但不是必须的(。

这两个问题都源于同一个问题:它与构造正则表达式的方式有关:

(regexp-opt x-blabla 'words)

问题出在'words参数上。这样做的目的是将生成的正则表达式封装在<。。。CCD_ 14对。根据Emacs手册,这些特殊字符类定义如下:

<    
matches the empty string, but only at the beginning of a word. 
‘<’ matches at the beginning of the buffer only if a word-constituent
character follows.
>
matches the empty string, but only at the end of a word. 
‘>’ matches at the end of the buffer only if the contents end with a
word-constituent character.

现在,"单词的开头">对Emacs来说意味着什么?这取决于模式。事实上,每个主要模式都定义了自己的语法表,它是字符到语法代码的映射。有许多预定义的类,其中之一是"w",它将字符定义为单词组成部分。通常,基于文本的模式会将字母a...zA...Z定义为具有语法代码"w",但也可能具有其他字符(例如连字符-(。

好吧,回到手头的问题上来。例如x-keywords,根据您的定义,得到的x-keywords-regexp是:

"\<\(#\(?:author\|comment\|\(?:gam\|titl\)e\)\)\>"

(请注意,在字符串中,反斜杠是一个特殊字符,用于转义其他特殊字符,例如nt。因此,为了对一个简单的反斜杠本身进行编码,您必须用另一个反斜杠来引用它。(

如上所述,我们分别在正则表达式的开头和结尾看到<>(或者,用字符串的说法:"\<""\>"(。但是,正如我们刚刚了解到的,为了使正则表达式匹配,潜在匹配的第一个和最后一个字符都需要具有单词组成语法。

字母是不挑剔的,但让我们通过键入C-h s:来检查#的语法代码

The parent syntax table is:
C-@ .. C-h      .       which means: punctuation
TAB .. C-j              which means: whitespace
C-k             .       which means: punctuation
C-l .. RET              which means: whitespace
C-n .. C-_      .       which means: punctuation
SPC                     which means: whitespace
!               .       which means: punctuation
"               "       which means: string
#               .       which means: punctuation
...

(明显被截断。(

就在那儿!#字符没有的单词组成语法,它被视为标点符号。

但我们可以通过在主模式的定义中加入以下行来改变这一点:

(modify-syntax-entry ?# "w" mml-mode-syntax-table)

?#是字符在Emacs-lisp中的编码方式(想想C中的'#'(。

关于问题的第二部分,为了匹配类似o75的内容,我们必须做类似的事情:将所有数字定义为单词成分:

(modify-syntax-entry '(?0 . ?9) "w" mml-mode-syntax-table)

然而,我们还需要编写一个合适的正则表达式来匹配这些关键字。正则表达式本身并不困难:

"o[0-9A-F]\{2\}"

但是,放在哪里呢?由于它已经是一个regexp,我们不能简单地将它添加到x-keywords中,因为这是一个简单字符串列表。

然而,我们可以将其连接到x-keywords-regexp,方法是将上面代码中的相应行更改为:

(x-keywords-regexp (concat (regexp-opt x-keywords 'words)
"\|\<[o][0-9A-F]\{2\}\>"))

请注意字符串参数开头的"\|",这是用于替代匹配的regexp语法。

最新更新