【问题标题】:Highlighting correctly in an emacs major mode在 emacs 主要模式下正确突出显示
【发布时间】:2011-02-27 13:47:33
【问题描述】:

我正在为一种语言(又名 mydsl)开发一个 emacs 主模式。但是,由于某种原因,使用 xahlee 网站上的技术似乎不起作用(可能是较旧的 emacs 方言..)

我要解决的关键问题是 (1) 突出显示 cmets 不起作用,(2) 使用 regexp-opt 行不起作用。

我查看了 GNU 手册并查看了 cc-mode 和 elisp mode...这些比我需要的要复杂得多。

;;;Standard # to newline comment
;;;Eventually should also have %% to %% multiline block comments

(defun mydsl-comment-dwim (arg)
  "comment or uncomment"
  (interactive "*P")
  (require 'newcomment)
  (let
      ((deactivate-mark nil)
       (comment-start "#")
       (comment-end "")
       comment-dwim arg)))

(defvar mydsl-events
  '("reservedword1"  
    "reservedword2"))

(defvar mydsl-keywords
  '("other-keyword" "another-keyword"))

;;Highlight various elements
(setq mydsl-hilite
      '(
        ; stuff between "
        ("\"\\.\\*\\?" . font-lock-string-face)
        ; : , ; { } =>  @ $ = are all special elements
        (":\\|,\\|;\\|{\\|}\\|=>\\|@\\|$\\|=" . font-lock-keyword-face)
        ( ,(regexp-opt mydsl-keywords 'words) . font-lock-builtin-face)
        ( ,(regexp-opt mydsl-events 'words) . font-lock-constant-face)
))


(defvar mydsl-tab-width nil "Width of a tab for MYDSL mode")

(define-derived-mode mydsl-mode fundamental-mode
  "MYDSL mode is a major mode for editing MYDSL  files"
  ;Recommended by manual
  (kill-all-local-variables)
  (setq mode-name "MYDSL script")
  (setq font-lock-defaults '((mydsl-hilite)))  
  (if (null mydsl-tab-width)
      (setq tab-width mydsl-tab-width)
    (setq tab-width default-tab-width)
    )

  ;Comment definitions
  (define-key mydsl-mode-map [remap comment-dwim] 'mydsl-comment-dwim)
  (modify-syntax-entry ?# "< b" mydsl-mode-syntax-table)
  (modify-syntax-entry ?\n "> b" mydsl-mode-syntax-table)
  ;;A gnu-correct program will have some sort of hook call here.
  )

(provide 'mydsl-mode)

【问题讨论】:

  • 你知道 Xah 的网站是讽刺的,对吧?
  • @jrockway - 他的 emacs 东西似乎大多是可靠的。我不确定你的意思。
  • 我不能代表 jrockway,虽然我发现 Xah 关于 Emacs 的信息多产且用心良苦,但它经常偏离 Emacs lisp 规范和约定,我认为它们教错了东西。例如mydsl-comment-dwim 是自定义 comment 行为的错误方法。同样,在 Xah 的页面上,我很快找到了一个 wrap-markup 定义,它(虽然是功能性的)打破了接受参数并使用 (interactive "r") 传递区域的约定。

标签: emacs major-mode


【解决方案1】:

您的代码中有几个语法问题,但您几乎正确。这是我编辑的版本,它似乎对mydsl-mode 中的缓冲区做了正确的事情:

; No changes to the simple vars
(defvar mydsl-events
  '("reservedword1"  
    "reservedword2"))

(defvar mydsl-keywords
  '("other-keyword" "another-keyword"))

;; I'd probably put in a default that you want, as opposed to nil
(defvar mydsl-tab-width nil "Width of a tab for MYDSL mode")

;; Two small edits.
;; First is to put an extra set of parens () around the list
;; which is the format that font-lock-defaults wants
;; Second, you used ' (quote) at the outermost level where you wanted ` (backquote)
;; you were very close
(defvar mydsl-font-lock-defaults
  `((
     ;; stuff between "
     ("\"\\.\\*\\?" . font-lock-string-face)
     ;; ; : , ; { } =>  @ $ = are all special elements
     (":\\|,\\|;\\|{\\|}\\|=>\\|@\\|$\\|=" . font-lock-keyword-face)
     ( ,(regexp-opt mydsl-keywords 'words) . font-lock-builtin-face)
     ( ,(regexp-opt mydsl-events 'words) . font-lock-constant-face)
     )))

(define-derived-mode mydsl-mode fundamental-mode "MYDSL script"
  "MYDSL mode is a major mode for editing MYDSL  files"

  ;; fundamental-mode kills all local variables, no need to do it again
  (setq mode-name "MYDSL script")

  ;; you again used quote when you had '((mydsl-hilite))
  ;; I just updated the variable to have the proper nesting (as noted above)
  ;; and use the value directly here
  (setq font-lock-defaults mydsl-font-lock-defaults)

  ;; when there's an override, use it
  ;; otherwise it gets the default value
  (when mydsl-tab-width
    (setq tab-width mydsl-tab-width))

  ;; for comments
  ;; overriding these vars gets you what (I think) you want
  ;; they're made buffer local when you set them
  (setq comment-start "#")
  (setq comment-end "")

  (modify-syntax-entry ?# "< b" mydsl-mode-syntax-table)
  (modify-syntax-entry ?\n "> b" mydsl-mode-syntax-table)
  ;;A gnu-correct program will have some sort of hook call here.
  )

(provide 'mydsl-mode)

【讨论】:

  • 修改语法条目的东西来自xahlee.org/emacs/elisp_comment_handling.html。修改语法条目的东西是 - 我想?管理注释处理的正确方法,否则 emacs 将突出显示 cmets 中的代码。无论如何,评论代码不起作用。
  • 注意-comment-dwim 重映射让comment-dwim 在mydsl-mode 下正常工作。根据 Xahlee 的说法,修改语法条目描述符应该创建注释突出显示。
  • @PaulNathan 我看不出我所拥有的(设置评论变量和仅使用 comment-dwim 本机,以及 Xah 所写的)之间有任何区别。 comment-dwim 使用我的代码使用 # 字符注释掉一个区域。 Emacs 23.1.
  • @Trey - 嗯。我想出了comment-dwim,但语法表修改仍然不起作用。我觉得我错过了一些完全明显的东西。我尝试过不同的颜色主题。我有最新的 emacs 23。
  • @Paul 你是什么意思语法表修改不起作用?需要更多信息。我在新的 Emacs 中注释掉 modify-syntax-entry 行并获得适当的注释突出显示。
猜你喜欢
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多