如何匹配不对称括号\[...]

wolfram-mode中常常会用到\[...]的格式表示常量,比如\[Pi],\[transpose] 但是emacs在匹配括号时会认为\[是一个被转义的符号,这个问题在 Unmatched [ … ] · Issue #4 · kawabata/wolfram-mode 中也有描述,但是由于这个库年久失修无人问津,我想自己动手解决,所以跑去把源代码翻了出来求教各位高手,不知到有没有什么好办法?

主要代码:

[details=wolfram-mode-20140118.757.el]括号匹配、转义符的syntax-table

(defvar wolfram-mode-syntax-table
  (let ((syntax-table (make-syntax-table)))

    ;; ...

    ;; comments and parens
    (modify-syntax-entry ?( "()1n" syntax-table)
    (modify-syntax-entry ?) ")(4n" syntax-table)
    (modify-syntax-entry ?* "_ 23n" syntax-table)

    ;; pure parens 
    (modify-syntax-entry ?[ "(]" syntax-table)
    (modify-syntax-entry ?] ")[" syntax-table)
    (modify-syntax-entry ?{ "(}" syntax-table)
    (modify-syntax-entry ?} "){" syntax-table)

    ;;想达到如下的效果,但是syntax里面好像并不支持多字符匹配
    ;;(modify-syntax-entry ?\\[ "(]" syntax-table)
    ;;(modify-syntax-entry ?] ")\\[" syntax-table)

    ;; ...

    ;; quotes
    ;;想到过把反斜线转义去掉,但是在smartparent中仍然认为\[和]不匹配
    (modify-syntax-entry ?\\ "\\" syntax-table) 
    (modify-syntax-entry ?\" "\"" syntax-table) 

   ;; ...

    syntax-table)
  "Syntax table used in `wolfram-mode'.")

font-lock关键字:


(defvar wolfram-font-lock-keywords
  '(

    ;; ...
    
    ;; 这里已经声明了\[..]是一个数学常量
    ("\\\\[[A-Za-z][A-Za-z0-9]*\]" . font-lock-constant-face )

    ;; ...

    ))

wolfram-smie-rules函数:(好像是根据括号匹配对下一行进行缩进,因为\[]不匹配,所以会对齐到上一行的末尾)

(defun wolfram-smie-rules (kind token)
  "Wolfram Language SMIE indentation function for KIND and TOKEN."
  (pcase (cons kind token)
    (`(:before . "[")
     (save-excursion
       (smie-default-backward-token)
       `(column . ,(current-column))))
    (`(:after . ":=") `(column . ,wolfram-indent))
    (`(:after . ,(or "]" "}" ")")) '(column . 0))
    (`(:after . ,(or "[" "{" "("))
     (save-excursion
       (beginning-of-line)
       (skip-chars-forward " \t")
       `(column . ,(+ wolfram-indent (current-column)))))
    (`(,_ . ";") (smie-rule-separator kind))
    (`(,_ . ",") (smie-rule-separator kind))
    (`(:elem . ,_) 0)
    (t nil)))
```[/details]

因为刚刚接触elisp,所以源代码不是很懂,挑了些感觉有用的地方,如果哪位高手能够帮助,我将非常感谢!


----------

已找到答案[Emacs major-mode for Mathematica based on cc-mode](http://stackoverflow.com/questions/15331277/emacs-major-mode-for-mathematica-based-on-cc-mode)

具体如下:

1. 在代码中加入`syntax-propertize-function`:

        (defvar wolfram-syntax-propertize-function
          (syntax-propertize-rules
           ("\\\\[[A-Z][A-Za-z]*]" (0 "_"))))

2. `wolfram-mode-variables ()`中加入如下代码:

        (setq-local syntax-propertize-function
                    wolfram-syntax-propertize-function)

不足之处在于`\[`和`]`不能使用`evil-jump-item`命令相互跳转
也感谢@xuchunyang 和 @twlz0ne  的帮助!
2 个赞

\ 的转义的意思去掉?比如改成标点

(modify-syntax-entry ?\\ ".")

我试了下缩进似乎变正常了,不清楚有什么副作用。

这不是 smartparens 的锅。

我是这样改的,必须声明一下,我并不了解这个 wolfram-mode,只是为了使得 \[] 看上去能配对:

    ;; quotes
    ;; (modify-syntax-entry ?\\ "\\" syntax-table)
    (modify-syntax-entry ?\\ "([" syntax-table)

效果:

(\[transpose] 变红色是因为切换窗口之前光标落在右]上)

你好,感谢回复,这样的话有办法在字符串中高亮转义的字符吗?例如\n \t等。 我试了一下好像不行,"abcd\"efgh"的左半边识别成字符串右半边变成了代码。

你这个语法我看不懂,是想把\变成[的左匹配吗?

那和(modify-syntax-entry ?\\ "." syntax-table)一样不能识别字符串中的\"

不一样的,"." 表示一个独立的标点符号,语法着色明显能看出来不同。

要匹配 \" 可以再写一条做匹配规则。

有关\"的转义还请具体指教

1 个赞

这道问答里的注释非常好…其实我也是刚刚才去看了下 modify-syntax-entry,语法真是反人类 :sweat_smile: