我必须遵守C风格指南,其中包含以下关于多行评论的内容:
多行注释应遵循以下规则:
//
开头的评论不得用于多行评论。/*
应单独在一条线上,或者,如果它是doxygen多线注释,则应出现在一行的开头。 */
应该是一行。*/
应与开头/*
对齐。/*
和*/
的一个制表位。示例:
/*
Comment.
More text.
*/
然而,emacs似乎无法以不同方式处理最后一个评论行并将其缩进,如下所示:
/*
Comment.
More text.
*/
有没有人知道如何说服emacs以不同方式处理上一个评论行,这与处理语句中的括号(例如defun-close
,block-close
)的处理方式不同?
答案 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 ,光标位于多行注释上。
修改强>
根据您的评论,至少有两种方法可以将其设为默认值:
为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)
使用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