4

基本上,我试图以我想要的方式突出显示以下咖啡脚本代码。可以在这里找到咖啡脚本函数的语法解释。

nameHere = (tstamp, moo, boo) ->
    ...

名称 tstamp、moo 和 boo 应该是粉红色的(没有别的,不是逗号,也不是括号),因为它们是 lambda 函数的参数。

highOrderFun ((x) -> x * x) someList

这里是第一个 x 是参数。参数可以有默认参数:

class Foo
    meth: (msg = "Hello", bar = "foo") ->
        ....

默认参数本身可以是变量:

defColor = "red"
print = (msg, color = defColor) ->
    ...

somsgcolorabove 应该突出显示,但不是defColor. 一个更棘手的情况是带有默认参数的函数,它们本身就是函数。我认为 emacs 的 font-lock 很难正确突出显示,但我还是把它包括在内:

funTakingFuns = (f1 = ((a, b) -> a*b), f2 = ((c, d) -> c/d)) ->
    ...

这似乎在 emacs 中实现起来相当复杂,因为您希望突出显示是上下文敏感的。我已经阅读了有关 font-lock 的文档,但无法弄清楚。

如果有人能告诉我要设置什么以font-lock-defaults使其语法突出显示我想要的方式,我将不胜感激。

更新显示更多咖啡脚本语法示例。

4

2 回答 2

8

font-lock-keywords允许MATCHER字段中的函数值:

whereMATCHER可以是要搜索的正则表达式,也可以是要调用以进行搜索的函数名称(使用一个参数调用,即搜索的限制;它应该返回 non- nil,移动点,match-data如果成功则适当设置;re-search-forward就像)。

所以我们需要编写一个函数来搜索缓冲区中的下一个函数参数。

像这样的东西:

    (defun coffee-match-next-argument (limit)
      (let ((start (point)))
        ;; Look for the arrow.
        (when (re-search-forward ") *->" limit t)
          ;; Save the position of the closing paren.
          (let ((stop (point)))
            (goto-char (match-beginning 0))
            ;; Go to the opening paren.
            (goto-char (nth 1 (syntax-ppss)))
            ;; If we're before our initial position, go forward.
            ;; We don't want to find the same symbols again.
            (when (> start (point))
              (goto-char start))
            ;; Look for the next symbol until the arrow.
            (or (re-search-forward "\\((\\|,\\) *\\(\\(\\sw\\|_\\)+\\)" stop 'mv)
                (coffee-match-next-argument limit))))))

和设置,与现有的一起使用coffee-mode

(font-lock-add-keywords
 'coffee-mode
 '((coffee-match-next-argument 2 font-lock-variable-name-face)))

当然,您也可以在 中使用它font-lock-defaults

这可能会使用粉色以外的其他颜色,但这很容易改变。

于 2013-02-03T18:09:20.907 回答
2

这更像是一种 hack,它远非最佳(因为我对咖啡脚本一点也不熟悉),但也许你自己稍微调整一下,你就可以完成这项工作。

所有的成分都在那里。

命令/功能的触发基于您使用coffee-mode. 如果你不这样做,这不是一个大麻烦,你只需要以不同的方式钩住这些东西。

将以下行放入您的.emacs:

(eval-after-load 'coffee '(load "/PATH/custom-coffee-font-lock.el"))

您可以将以下文本保存为文件,它将:

(1) 触发时字体锁定coffee-mode

>(2)在“->”中键入“”时字体锁定当前行

(3) 允许通过运行字体锁定缓冲区M-x coffee-init-font-lock

;;;; custom-coffee-font-lock

;; Firstly, create a new font for this. 

(make-face 'font-lock-coffeescript-face)
(set-face-foreground 'font-lock-coffeescript-face "pink")


;; Next, one function that should be ran after a file is identified as 
;; a coffeescript file. It will do the font-locking you want on 
;; the whole buffer. It is also possible to run it manually. 


(defun coffee-init-font-lock ()
  (interactive)
  (save-excursion 
    (goto-char 1)
    (while (search-forward-regexp "=.+->" nil t)
      (search-backward-regexp "(")
      (forward-char 1)
      (add-text-properties 
       (point) (- (search-forward-regexp "," nil nil) 1) 
       '(font-lock-face font-lock-coffeescript-face))
      (add-text-properties 
       (point)  (- (search-forward-regexp "," nil nil) 1) 
       '(font-lock-face font-lock-coffeescript-face))
      (add-text-properties 
       (point)  (- (search-forward-regexp ")" nil nil) 1) 
       '(font-lock-face font-lock-coffeescript-face))
      (move-end-of-line 1)))
  )

  ;; This actually runs that function.
  (coffee-init-font-lock)


;; This advice will be ran everytime you write something. It will check 
;; whether "->" is before it, so when you type the final ">", it will
;; do the font locking for the current line (it also checks for your mode).

(defadvice self-insert-command (after coffee-font-lock activate)
  (when (and (looking-back "->") (eq major-mode 'coffee-mode))
    (save-excursion 
        (search-backward-regexp "(")
        (forward-char 1)
        (add-text-properties 
         (point)  (- (search-forward-regexp "," nil nil) 1) 
         '(font-lock-face font-lock-coffeescript-face))
        (add-text-properties 
         (point)  (- (search-forward-regexp "," nil nil) 1) 
         '(font-lock-face font-lock-coffeescript-face))
        (add-text-properties 
         (point)  (- (search-forward-regexp ")" nil nil) 1) 
         '(font-lock-face font-lock-coffeescript-face))))
  )

(provide 'custom-coffee-font-lock)
;;; custom-coffee-font-lock.el

如果您有任何要求,请告诉我。就像我说的,我不使用 CoffeeScript,所以这可能会给你带来巨大的错误。至少它应该有助于一些基本的想法。

结果:

在此处输入图像描述

于 2013-02-03T16:20:00.450 回答