diff options
| -rw-r--r-- | lisp/progmodes/c-ts-common.el | 109 | ||||
| -rw-r--r-- | test/lisp/progmodes/c-ts-mode-resources/filling.erts | 46 |
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 | |||
| 218 | This 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 | ||
| 7 | Point-Char: | | 7 | Point-Char: | |
| 8 | 8 | ||
| 9 | Name: 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 | |||
| 18 | Name: 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 | |||
| 29 | Name: 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 | |||
| 42 | Name: 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 | |||
| 9 | Name: Type 1 | 55 | Name: Type 1 |
| 10 | 56 | ||
| 11 | =-= | 57 | =-= |