有没有一种方法可以在emacs中获得等效的defun-close for multi-line comment indent?

时间:2014-09-11 17:54:30

标签: emacs coding-style

我必须遵守C风格指南,其中包含以下关于多行评论的内容:

多行注释应遵循以下规则:

  1. //开头的评论不得用于多行评论。
  2. 开口/*应单独在一条线上,或者,如果它是doxygen多线注释,则应出现在一行的开头。
  3. 结束*/应该是一行。
  4. 结束*/应与开头/*对齐。
  5. 多行注释的正文应缩进相对于/**/的一个制表位。
  6. 示例:

    /*
        Comment.
        More text.
    */
    

    然而,emacs似乎无法以不同方式处理最后一个评论行并将其缩进,如下所示:

    /*
        Comment.
        More text.
        */
    

    有没有人知道如何说服emacs以不同方式处理上一个评论行,这与处理语句中的括号(例如defun-closeblock-close)的处理方式不同?

1 个答案:

答案 0 :(得分:0)

编辑:这不是您问题的直接答案,但应解决您的要求。

这可能不是最漂亮的解决方案,但它运作良好。

如果更改句法符号c的偏移量(发出 Mx c-set-offset RET ,光标位于多行注释上)到c-lineup-C-comments你会得到类似于你想要的东西,但评论文字相对于开头*缩进1个字符。

以下是c-lineup-C-comments的修改版本,用c-basic-offset个空格缩进评论文字。

(defun my-c-lineup-C-comments (langelem)
  "Line up C block comment continuation lines.
Various heuristics are used to handle many of the common comment
styles.  Some examples:

/*          /**         /*         /* text      /*          /**
 * text      * text       text        text      ** text      ** text
 */          */         */         */           */           */

/*********************************************************************
 * text
 ********************************************************************/

/*********************************************************************
    Free form text comments:
 In comments with a long delimiter line at the start, the indentation
 is kept unchanged for lines that start with an empty comment line
 prefix.  The delimiter line is whatever matches the
 `comment-start-skip' regexp.
*********************************************************************/

The variable `c-comment-prefix-regexp' is used to recognize the
comment line prefix, e.g. the `*' that usually starts every line
inside a comment.

Works with: The `c' syntactic symbol."
  (save-excursion
    (let* ((here (point))
       (prefixlen (progn (back-to-indentation)
                 (if (looking-at c-current-comment-prefix)
                 (- (match-end 0) (point))
                   0)))
       (starterlen
        ;; Get the length of the comment starter, not including
        ;; the first '/'. We check if the comment prefix matched
        ;; on the current line matches the starter or if it
        ;; matches comment-start-skip, and choose whichever is
        ;; longest.
        (max (save-excursion
           (goto-char (1+ (c-langelem-pos langelem)))
           (if (and (match-string 0)
                (looking-at (regexp-quote (match-string 0))))
               (- (match-end 0) (match-beginning 0))
             0))
         (save-excursion
           (goto-char (c-langelem-pos langelem))
           (looking-at comment-start-skip)
           (- (or (match-end 1)
              (save-excursion
                (goto-char (match-end 0))
                (skip-chars-backward " \t")
                (point)))
              (point)
              1)))))
      (if (and (> starterlen 10) (zerop prefixlen))
      ;; The comment has a long starter and the line doesn't have
      ;; a nonempty comment prefix.  Treat it as free form text
      ;; and don't change the indentation.
      (vector (current-column))
    ;; Go back to the previous non-blank line, if any.
    (while
        (progn
          (forward-line -1)
          (back-to-indentation)
          (and (> (point) (c-langelem-pos langelem))
           (looking-at "[ \t]*$"))))
    ;; Is the starting line the first continuation line with content?
    (if (>= (c-langelem-pos langelem) (point))
        (if (zerop prefixlen)
        ;; No nonempty comment prefix. Align after comment
        ;; starter.
        (progn
          (looking-at comment-start-skip)
          (goto-char (match-end 0))
          ;; The following should not be necessary, since
          ;; comment-start-skip should match everything (i.e.
          ;; typically whitespace) that leads up to the text.
          ;;(if (looking-at "\\([ \t]+\\).+$")
          ;;    ;; Align with the text that hangs after the
          ;;    ;; comment starter.
          ;;    (goto-char (match-end 1)))
          ;;
          ;; EDITED HERE: this line was 
          ;; (vector (current column))
          (vector (+ (- c-basic-offset 1 starterlen) (current-column))))
          ;; How long is the comment starter?  if greater than the
          ;; length of the comment prefix, align left.  if less
          ;; than or equal, align right.  this should also pick up
          ;; Javadoc style comments.
          (if (> starterlen prefixlen)
          (progn
            (goto-char (c-langelem-pos langelem))
            (vector (+ 1 (current-column) )))
        (goto-char (+ (c-langelem-pos langelem) starterlen 1))
        (vector (- (current-column) prefixlen))))
      ;; We didn't start on the first non-blank continuation line.  If the
      ;; previous line has a nonempty comment prefix, align with it.
      ;; Otherwise, align with the previous nonempty line, but align the
      ;; comment ender with the starter.
      (when (or (not (looking-at c-current-comment-prefix))
            (eq (match-beginning 0) (match-end 0)))
        (goto-char here)
        (back-to-indentation)
        (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/"))
        (goto-char (c-langelem-pos langelem))
          (while (and (zerop (forward-line -1))
              (looking-at "^[ \t]*$")))
          (back-to-indentation)
          (if (< (point) (c-langelem-pos langelem))
          ;; Align with the comment starter rather than
          ;; with the code before it.
          (goto-char (c-langelem-pos langelem)))))
      (vector (current-column)))))))

您可以使用它发出 M-x c-set-offset RET ,光标位于多行注释上。

修改

根据您的评论,至少有两种方法可以将其设为默认值:

  1. c-mode-hook添加一个钩子:

    (defun my-c-mode-hook ()
      (c-set-offset 'c 'my-c-lineup-C-comments))
    (add-hook 'c-mode-hook 'my-c-mode-hook)
    
  2. 使用c-add-style添加新的C样式并将其设置为默认自定义c-default-style

    (c-add-style "mystyle"
      '("awk" ;; or whatever style you are currently using!
          (c-offsets-alist
             (c . my-c-lineup-C-comments)
          )
       )
    )
    

    要自定义c-default-style,请键入

    M-X customize-variable RET c-default-style RET