如何在Emacs中定义整行注释语法?

时间:2014-08-11 14:16:45

标签: emacs comments elisp

我希望序列//在行的开头处开始注释。但在一行内,它不应该开始任何评论。

// this is a comment
This is a URL: http://example.com

有可能吗?

2 个答案:

答案 0 :(得分:6)

我这样做:

(defvar my-foo-mode-syntax-table
  (let ((st (make-syntax-table)))
    ;; Add other entries appropriate for my-foo-mode.
    (modify-syntax-entry ?/ ". 12" st)
    (modify-syntax-entry ?\n "> " st)
    st))

(defvar my-foo-font-lock-keywords
  ;; Add other rules appropriate for my-foo-mode.
  ())

(define-derived-mode my-foo-mode nil "My-Foo"
  (setq-local font-lock-keywords '(my-foo-font-lock-keywords))
  ;; Add other settings appropriate for my-foo-mode.
  (setq-local syntax-propertize-function
              (syntax-propertize-rules ("./\\(/+\\)" (1 ".")))))

注意:不需要任何特殊的字体锁定规则,因为font-lock会根据语法表自动为您突出显示注释。

答案 1 :(得分:5)

您可以写syntax-propertize-function

来完成此操作

我写了一个示例主要模式,显示如下。 内置解析的Emacs将调用您的syntax-propertize-function,以便它可以在以//开头的行上手动设置syntax-table文本属性。

(define-derived-mode my-syntax-test-mode fundamental-mode
  "A major mode where // denotes a comment but only if it is at the beginning of a line."
  :syntax-table (make-syntax-table) 
  (setq mode-name "my syntax test")
  ;; our mode will use `apply-my-custom-syntax-table-appropriately' to manually set
  ;; the syntax-table text property on lines starting with //"
  (setq syntax-propertize-function 'apply-my-custom-syntax-table-appropriately)
  ;; change `comment-dwim` to handle this type of comments correctly
  (local-set-key [remap comment-dwim] 'my-comment-dwim))

(defvar my-custom-syntax-table
  ;; syntax table where // starts a comment and \n ends it
  (let ((table (make-syntax-table)))
    (modify-syntax-entry ?/ "< 1" table)
    (modify-syntax-entry ?/ "< 2" table)
    (modify-syntax-entry ?\n "> " table)
    table))

(defun apply-my-custom-syntax-table-appropriately (beg end)
  (save-excursion
    (save-restriction
      (widen)
      (goto-char beg)
      ;; for every line between points BEG and END
      (while (and (not (eobp)) (< (point) end))
        (beginning-of-line)
        ;; if it starts with a //
        (when (looking-at "^//")
          ;; remove current syntax-table property
          (remove-text-properties (1- (line-beginning-position))
                                  (1+ (line-end-position))
                                  '(syntax-table))
          ;; set syntax-table property to our custom one
          ;; for the whole line including the beginning and ending newlines
          (add-text-properties (1- (line-beginning-position))
                               (1+ (line-end-position))
                               (list 'syntax-table my-custom-syntax-table)))
        (forward-line 1)))))

(defun my-comment-dwim (arg)
  (interactive "*P")
  (require 'newcomment)
  (save-excursion
    (let ((comment-start "//") (comment-end "")
          (comment-column 0)
          ;; don't indent comments
          (comment-style 'plain))
      ;; create the region containing current line if there is no active region
      (unless (use-region-p)
        (end-of-line)
        (push-mark (line-beginning-position))
        (setq mark-active t))
      (comment-dwim nil))))