aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2024-07-27 14:50:19 -0700
committerYuan Fu2024-07-30 17:09:58 -0700
commit74bb1e5897f4532fbdefddada28258a8d3d5c95f (patch)
treeaf8687678575aa6457660ca861cc8ad923fe58ba
parente4cd26defc0e1a6deafbe4b2310ebdb3ffa4578f (diff)
downloademacs-74bb1e5897f4532fbdefddada28258a8d3d5c95f.tar.gz
emacs-74bb1e5897f4532fbdefddada28258a8d3d5c95f.zip
Fix filling in c-ts-mode (bug#72116)
The previous fix introduced a regression in the case when there's only a single line in the block comment. In that case we don't want to add a start at the second line: /* foo foo foo */ should => /* foo foo foo */ rather than /* foo foo * foo */ This commit fixes that. * lisp/progmodes/c-ts-common.el: (c-ts-common--fill-block-comment): Don't mask the /*. (c-ts-common--adaptive-fill-prefix): New function. (c-ts-common-comment-setup): Don't set adaptive-regexp, change adaptive-fill-first-line-regexp to work with the new adaptive-fill-function. * test/lisp/progmodes/c-ts-mode-resources/filling.erts: New tests
-rw-r--r--lisp/progmodes/c-ts-common.el109
-rw-r--r--test/lisp/progmodes/c-ts-mode-resources/filling.erts46
2 files changed, 110 insertions, 45 deletions
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 6c0b1c9100d..022d21e11a1 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -153,16 +153,16 @@ comment."
153 (end-marker nil) 153 (end-marker nil)
154 (end-len 0)) 154 (end-len 0))
155 (move-marker start-marker start) 155 (move-marker start-marker start)
156 ;; We mask "/*" and the space before "*/" like 156 ;; If the first line is /* followed by non-text, exclude this line
157 ;; `c-fill-paragraph' does. 157 ;; from filling.
158 (atomic-change-group 158 (atomic-change-group
159 ;; Mask "/*".
160 (goto-char start) 159 (goto-char start)
161 (when (looking-at (rx (* (syntax whitespace)) 160 (when (looking-at (rx (* (syntax whitespace))
162 (group "/") "*")) 161 (group "/") "*"
163 (goto-char (match-beginning 1)) 162 (* (or "*" "=" "-" "/" (syntax whitespace)))
164 (move-marker start-marker (point)) 163 eol))
165 (replace-match " " nil nil nil 1)) 164 (forward-line)
165 (move-marker start-marker (point)))
166 166
167 ;; Include whitespaces before /*. 167 ;; Include whitespaces before /*.
168 (goto-char start) 168 (goto-char start)
@@ -206,16 +206,63 @@ comment."
206 (fill-region (max start-marker para-start) (min end para-end) arg)) 206 (fill-region (max start-marker para-start) (min end para-end) arg))
207 207
208 ;; Unmask. 208 ;; Unmask.
209 (when start-marker
210 (goto-char start-marker)
211 (delete-char 1)
212 (insert "/"))
213 (when end-marker 209 (when end-marker
214 (goto-char end-marker) 210 (goto-char end-marker)
215 (delete-region (point) (+ end-len (point))) 211 (delete-region (point) (+ end-len (point)))
216 (insert (make-string end-len ?\s))) 212 (insert (make-string end-len ?\s)))
217 (goto-char orig-point)))) 213 (goto-char orig-point))))
218 214
215(defun c-ts-common--adaptive-fill-prefix ()
216 "Returns the appropriate fill-prefix for this paragraph.
217
218This function should be called at BOL. Used by
219`adaptive-fill-function'."
220 (cond
221 ;; (1)
222 ;; If current line is /* and next line is * -> prefix is *.
223 ;; Eg:
224 ;; /* xxx => /* xxx
225 ;; * xxx xxx * xxx
226 ;; * xxx
227 ;; If current line is /* and next line isn't * or doesn't exist ->
228 ;; prefix is whitespace.
229 ;; Eg:
230 ;; /* xxx xxx */ => /* xxx
231 ;; xxx */
232 ((and (looking-at (rx (* (syntax whitespace))
233 "/*"
234 (* "*")
235 (* (syntax whitespace))))
236 (let ((whitespaces (make-string (length (match-string 0)) ?\s)))
237 (save-excursion
238 (if (and (eq (forward-line) 0)
239 (looking-at (rx (* (syntax whitespace))
240 "*"
241 (* (syntax whitespace)))))
242 (match-string 0)
243 whitespaces)))))
244 ;; (2)
245 ;; Current line: //, ///, ////...
246 ;; Prefix: same.
247 ((looking-at (rx (* (syntax whitespace))
248 "//"
249 (* "/")
250 (* (syntax whitespace))))
251 (match-string 0))
252 ;; (3)
253 ;; Current line: *, |, -
254 ;; Prefix: same.
255 ;; This branch must return the same prefix as branch (1), as the
256 ;; second line in the paragraph; then the whole paragraph will use *
257 ;; as the prefix.
258 ((looking-at (rx (* (syntax whitespace))
259 (or "*" "|" "-")
260 (* (syntax whitespace))))
261 (match-string 0))
262 ;; Other: let `adaptive-fill-regexp' and
263 ;; `adaptive-fill-first-line-regexp' decide.
264 (t nil)))
265
219(defun c-ts-common-comment-setup () 266(defun c-ts-common-comment-setup ()
220 "Set up local variables for C-like comment. 267 "Set up local variables for C-like comment.
221 268
@@ -241,43 +288,15 @@ Set up:
241 (group (or (syntax comment-end) 288 (group (or (syntax comment-end)
242 (seq (+ "*") "/"))))) 289 (seq (+ "*") "/")))))
243 (setq-local adaptive-fill-mode t) 290 (setq-local adaptive-fill-mode t)
244 ;; This matches (1) empty spaces (the default), (2) "//", (3) "*", 291 (setq-local adaptive-fill-function #'c-ts-common--adaptive-fill-prefix)
245 ;; but do not match "/*", because we don't want to use "/*" as 292 ;; Always accept * or | as prefix, even if there's only one line in
246 ;; prefix when filling. (Actually, it doesn't matter, because 293 ;; the paragraph.
247 ;; `comment-start-skip' matches "/*" which will cause
248 ;; `fill-context-prefix' to use "/*" as a prefix for filling, that's
249 ;; why we mask the "/*" in `c-ts-common--fill-paragraph'.)
250 (setq-local adaptive-fill-regexp
251 (concat (rx (* (syntax whitespace))
252 (group (or (seq "/" (+ "/")) (* "*"))))
253 adaptive-fill-regexp))
254 ;; For (1): Note the missing * comparing to `adaptive-fill-regexp'.
255 ;; The reason for its absence is a bit convoluted to explain. Suffice
256 ;; to say that without it, filling a single line paragraph that starts
257 ;; with /* doesn't insert * at the beginning of each following line,
258 ;; and filling a multi-line paragraph whose first two lines start with
259 ;; * does insert * at the beginning of each following line. If you
260 ;; know how does adaptive filling work, you know what I mean.
261 ;;
262 ;; For (2): If we only have (1), filling a single line that starts
263 ;; with a single * (and not /*) in a block comment doesn't work as
264 ;; expected: the following lines won't be prefixed with *. So we add
265 ;; another rule to cover this case too. (See bug#72116.) I
266 ;; intentionally made the matching strict (it only matches if there
267 ;; are only a single * at the BOL) because I want to minimize the
268 ;; possibility of this new rule matching in unintended situations.
269 (setq-local adaptive-fill-first-line-regexp 294 (setq-local adaptive-fill-first-line-regexp
270 (rx bos 295 (rx bos
271 ;; (1) 296 (* (syntax whitespace))
272 (or (seq (* (syntax whitespace)) 297 (or "*" "|")
273 (group (seq "/" (+ "/"))) 298 (* (syntax whitespace))
274 (* (syntax whitespace)))
275 ;; (2)
276 (seq (* (syntax whitespace))
277 (group "*")
278 (* (syntax whitespace))))
279 eos)) 299 eos))
280 ;; Same as `adaptive-fill-regexp'.
281 (setq-local paragraph-start 300 (setq-local paragraph-start
282 (rx (or (seq (* (syntax whitespace)) 301 (rx (or (seq (* (syntax whitespace))
283 (group (or (seq "/" (+ "/")) (* "*"))) 302 (group (or (seq "/" (+ "/")) (* "*")))
diff --git a/test/lisp/progmodes/c-ts-mode-resources/filling.erts b/test/lisp/progmodes/c-ts-mode-resources/filling.erts
index e51e3658c83..e58b8e91c90 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/filling.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/filling.erts
@@ -6,6 +6,52 @@ Code:
6 6
7Point-Char: | 7Point-Char: |
8 8
9Name: Single line
10
11=-=
12/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy */
13=-=
14/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
15 woooomy */
16=-=-=
17
18Name: Two lines
19
20=-=
21/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
22 woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy */
23=-=
24/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
25 woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
26 woooomy */
27=-=-=
28
29Name: Two lines with star
30
31=-=
32/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
33 * woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
34 */
35=-=
36/* woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
37 * woooomy woooomy woooomy woooomy woooomy woooomy woooomy woooomy
38 * woooomy
39 */
40=-=-=
41
42Name: First line empty (bug#72116)
43
44=-=
45/**
46 * rsite nrsoti ernsto ierntires ntoritsen roitsenrsoit enrstoi ensrotie nrsit ensroit enrsoi ensrien
47 */
48=-=
49/**
50 * rsite nrsoti ernsto ierntires ntoritsen roitsenrsoit enrstoi
51 * ensrotie nrsit ensroit enrsoi ensrien
52 */
53=-=-=
54
9Name: Type 1 55Name: Type 1
10 56
11=-= 57=-=