Mercurial > hg > xemacs-beta
annotate lisp/newcomment.el @ 5839:d139eb1fead8
Check return value of fseek.
| author | Marcus Crestani <marcus@crestani.de> |
|---|---|
| date | Sat, 13 Dec 2014 14:09:33 +0100 |
| parents | b7ae5f44b950 |
| children | bbe4146603db |
| rev | line source |
|---|---|
| 1333 | 1 ;;; newcomment.el --- (un)comment regions of buffers |
| 2 | |
| 3 ;; Copyright (C) 1999, 2000 Free Software Foundation Inc. | |
| 4 | |
| 5 ;; Author: code extracted from Emacs-20's simple.el | |
| 6 ;; Maintainer: Stefan Monnier <monnier@cs.yale.edu> | |
| 7 ;; Keywords: comment uncomment | |
| 8 | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
9 ;; This file is part of XEmacs. |
| 1333 | 10 |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
11 ;; XEmacs is free software: you can redistribute it and/or modify it |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
12 ;; under the terms of the GNU General Public License as published by the |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
13 ;; Free Software Foundation, either version 3 of the License, or (at your |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
14 ;; option) any later version. |
| 1333 | 15 |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
16 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
18 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
19 ;; for more details. |
| 1333 | 20 |
| 21 ;; You should have received a copy of the GNU General Public License | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4435
diff
changeset
|
22 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>. |
| 1333 | 23 |
| 2511 | 24 ;;; Synched up with: FSF 21.3. |
| 25 | |
| 1333 | 26 ;;; Commentary: |
| 27 | |
| 28 ;; A replacement for simple.el's comment-related functions. | |
| 29 | |
| 30 ;;; Bugs: | |
| 31 | |
| 2511 | 32 ;; - boxed comments in Perl are not properly uncommented because they are |
| 33 ;; uncommented one-line at a time. | |
| 34 ;; - nested comments in sgml-mode are not properly quoted. | |
| 1333 | 35 ;; - single-char nestable comment-start can only do the "\\s<+" stuff |
| 36 ;; if the corresponding closing marker happens to be right. | |
| 37 ;; - uncomment-region with a numeric argument can render multichar | |
| 38 ;; comment markers invalid. | |
| 39 ;; - comment-indent or comment-region when called inside a comment | |
| 40 ;; will happily break the surrounding comment. | |
| 41 ;; - comment-quote-nested will not (un)quote properly all nested comment | |
| 42 ;; markers if there are more than just comment-start and comment-end. | |
| 43 ;; For example, in Pascal where {...*) and (*...} are possible. | |
| 44 | |
| 45 ;;; Todo: | |
| 46 | |
| 2511 | 47 ;; - rebox.el-style refill. |
| 48 ;; - quantized steps in comment-alignment. | |
| 49 ;; - try to align tail comments. | |
| 50 ;; - check what c-comment-line-break-function has to say. | |
| 51 ;; - spill auto-fill of comments onto the end of the next line. | |
| 1333 | 52 ;; - uncomment-region with a consp (for blocks) or somehow make the |
| 2511 | 53 ;; deletion of continuation markers less dangerous. |
| 54 ;; - drop block-comment-<foo> unless it's really used. | |
| 55 ;; - uncomment-region on a subpart of a comment. | |
| 56 ;; - support gnu-style "multi-line with space in continue". | |
| 1333 | 57 ;; - somehow allow comment-dwim to use the region even if transient-mark-mode |
| 58 ;; is not turned on. | |
| 59 | |
| 60 ;; - when auto-filling a comment, try to move the comment to the left | |
| 61 ;; rather than break it (if possible). | |
| 62 ;; - sometimes default the comment-column to the same | |
| 63 ;; one used on the preceding line(s). | |
| 64 | |
| 65 ;;; Code: | |
| 66 | |
| 67 (defalias 'indent-for-comment 'comment-indent) | |
| 68 (defalias 'set-comment-column 'comment-set-column) | |
| 69 (defalias 'kill-comment 'comment-kill) | |
| 70 (defalias 'indent-new-comment-line 'comment-indent-new-line) | |
| 71 | |
| 72 (defgroup comment nil | |
| 73 "Indenting and filling of comments." | |
| 74 :prefix "comment-" | |
| 75 :version "21.1" | |
| 76 :group 'fill) | |
| 77 | |
| 78 (defvar comment-use-syntax 'undecided | |
| 79 "Non-nil if syntax-tables can be used instead of regexps. | |
| 80 Can also be `undecided' which means that a somewhat expensive test will | |
| 81 be used to try to determine whether syntax-tables should be trusted | |
| 82 to understand comments or not in the given buffer. | |
| 83 Major modes should set this variable.") | |
| 84 | |
| 2511 | 85 (defcustom comment-fill-column nil |
| 86 "Column to use for `comment-indent'. If nil, use `fill-column' instead." | |
| 87 :type '(choice (const nil) integer)) | |
| 88 | |
| 1333 | 89 (defcustom comment-column 32 |
| 90 "*Column to indent right-margin comments to. | |
| 91 Each mode establishes a different default value for this variable; you | |
| 2511 | 92 can set the value for a particular mode using that mode's hook. |
| 93 Comments might be indented to a value smaller than this in order | |
| 94 not to go beyond `comment-fill-column'." | |
| 95 :type 'integer) | |
| 1333 | 96 (make-variable-buffer-local 'comment-column) |
| 97 | |
| 98 (defvar comment-start nil | |
| 99 "*String to insert to start a new comment, or nil if no comment syntax.") | |
| 100 | |
| 101 (defvar comment-start-skip nil | |
| 102 "*Regexp to match the start of a comment plus everything up to its body. | |
| 103 If there are any \\(...\\) pairs, the comment delimiter text is held to begin | |
| 104 at the place matched by the close of the first pair.") | |
| 105 | |
| 106 (defvar comment-end-skip nil | |
| 107 "Regexp to match the end of a comment plus everything up to its body.") | |
| 108 | |
| 109 (defvar comment-end "" | |
| 110 "*String to insert to end a new comment. | |
| 111 Should be an empty string if comments are terminated by end-of-line.") | |
| 112 | |
| 113 (defvar comment-indent-function 'comment-indent-default | |
| 114 "Function to compute desired indentation for a comment. | |
| 115 This function is called with no args with point at the beginning of | |
| 116 the comment's starting delimiter and should return either the desired | |
| 117 column indentation or nil. | |
| 118 If nil is returned, indentation is delegated to `indent-according-to-mode'.") | |
| 119 | |
| 120 (defvar block-comment-start nil) | |
| 121 (defvar block-comment-end nil) | |
| 122 | |
| 123 (defvar comment-quote-nested t | |
| 124 "Non-nil if nested comments should be quoted. | |
| 125 This should be locally set by each major mode if needed.") | |
| 126 | |
| 127 (defvar comment-continue nil | |
| 128 "Continuation string to insert for multiline comments. | |
| 129 This string will be added at the beginning of each line except the very | |
| 130 first one when commenting a region with a commenting style that allows | |
| 131 comments to span several lines. | |
| 132 It should generally have the same length as `comment-start' in order to | |
| 133 preserve indentation. | |
| 134 If it is nil a value will be automatically derived from `comment-start' | |
| 135 by replacing its first character with a space.") | |
| 136 | |
| 137 (defvar comment-add 0 | |
| 138 "How many more comment chars should be inserted by `comment-region'. | |
| 139 This determines the default value of the numeric argument of `comment-region'. | |
| 140 This should generally stay 0, except for a few modes like Lisp where | |
| 141 it can be convenient to set it to 1 so that regions are commented with | |
| 142 two semi-colons.") | |
| 143 | |
| 144 (defconst comment-styles | |
| 145 '((plain . (nil nil nil nil)) | |
| 146 (indent . (nil nil nil t)) | |
| 147 (aligned . (nil t nil t)) | |
| 148 (multi-line . (t nil nil t)) | |
| 149 (extra-line . (t nil t t)) | |
| 150 (box . (nil t t t)) | |
| 151 (box-multi . (t t t t))) | |
| 152 "Possible comment styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)). | |
| 153 STYLE should be a mnemonic symbol. | |
| 154 MULTI specifies that comments are allowed to span multiple lines. | |
| 155 ALIGN specifies that the `comment-end' markers should be aligned. | |
| 156 EXTRA specifies that an extra line should be used before and after the | |
| 157 region to comment (to put the `comment-end' and `comment-start'). | |
| 158 INDENT specifies that the `comment-start' markers should not be put at the | |
| 159 left margin but at the current indentation of the region to comment.") | |
| 160 | |
| 161 (defcustom comment-style 'plain | |
| 162 "*Style to be used for `comment-region'. | |
| 163 See `comment-styles' for a list of available styles." | |
| 164 :type (if (boundp 'comment-styles) | |
| 165 `(choice ,@(mapcar (lambda (s) `(const ,(car s))) comment-styles)) | |
| 166 'symbol)) | |
| 167 | |
| 168 (defcustom comment-padding " " | |
| 169 "Padding string that `comment-region' puts between comment chars and text. | |
| 170 Can also be an integer which will be automatically turned into a string | |
| 171 of the corresponding number of spaces. | |
| 172 | |
| 173 Extra spacing between the comment characters and the comment text | |
| 2511 | 174 makes the comment easier to read. Default is 1. nil means 0." |
| 1333 | 175 :type '(choice string integer (const nil))) |
| 176 | |
| 177 (defcustom comment-multi-line t ; XEmacs - this works well with adaptive fill | |
| 178 "*Non-nil means \\[indent-new-comment-line] should continue same comment | |
| 179 on new line, with no new terminator or starter. | |
| 180 This is obsolete because you might as well use \\[newline-and-indent]." | |
| 2511 | 181 :type 'boolean) |
| 1333 | 182 |
| 183 ;;;; | |
| 184 ;;;; Helpers | |
| 185 ;;;; | |
| 186 | |
| 187 (defun comment-string-strip (str beforep afterp) | |
| 188 "Strip STR of any leading (if BEFOREP) and/or trailing (if AFTERP) space." | |
| 189 (string-match (concat "\\`" (if beforep "\\s-*") | |
| 190 "\\(.*?\\)" (if afterp "\\s-*\n?") | |
| 191 "\\'") str) | |
| 192 (match-string 1 str)) | |
| 193 | |
| 194 (defun comment-string-reverse (s) | |
| 195 "Return the mirror image of string S, without any trailing space." | |
| 196 (comment-string-strip (concat (nreverse (string-to-list s))) nil t)) | |
| 197 | |
| 198 (defun comment-normalize-vars (&optional noerror) | |
| 199 (if (not comment-start) (or noerror (error "No comment syntax is defined")) | |
| 200 ;; comment-use-syntax | |
| 201 (when (eq comment-use-syntax 'undecided) | |
| 202 (set (make-local-variable 'comment-use-syntax) | |
| 203 (let ((st (syntax-table)) | |
| 204 (cs comment-start) | |
| 205 (ce (if (string= "" comment-end) "\n" comment-end))) | |
| 206 ;; Try to skip over a comment using forward-comment | |
| 207 ;; to see if the syntax tables properly recognize it. | |
| 208 (with-temp-buffer | |
| 209 (set-syntax-table st) | |
| 210 (insert cs " hello " ce) | |
| 211 (goto-char (point-min)) | |
| 212 (and (forward-comment 1) (eobp)))))) | |
| 213 ;; comment-padding | |
| 214 (unless comment-padding (setq comment-padding 0)) | |
| 215 (when (integerp comment-padding) | |
| 216 (setq comment-padding (make-string comment-padding ? ))) | |
| 217 ;; comment markers | |
| 218 ;;(setq comment-start (comment-string-strip comment-start t nil)) | |
| 219 ;;(setq comment-end (comment-string-strip comment-end nil t)) | |
| 220 ;; comment-continue | |
| 221 (unless (or comment-continue (string= comment-end "")) | |
| 222 (set (make-local-variable 'comment-continue) | |
| 223 (concat (if (string-match "\\S-\\S-" comment-start) " " "|") | |
| 2511 | 224 (substring comment-start 1))) |
| 225 ;; Hasn't been necessary yet. | |
| 226 ;; (unless (string-match comment-start-skip comment-continue) | |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
227 ;; (kill-local-variable 'comment-continue)) |
| 2511 | 228 ) |
| 1333 | 229 ;; comment-skip regexps |
| 2511 | 230 (unless (and comment-start-skip |
| 231 ;; In case comment-start has changed since last time. | |
| 232 (string-match comment-start-skip comment-start)) | |
| 1333 | 233 (set (make-local-variable 'comment-start-skip) |
| 234 (concat "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(\\s<+\\|" | |
| 235 (regexp-quote (comment-string-strip comment-start t t)) | |
| 236 ;; Let's not allow any \s- but only [ \t] since \n | |
| 237 ;; might be both a comment-end marker and \s-. | |
| 238 "+\\)[ \t]*"))) | |
| 2511 | 239 (unless (and comment-end-skip |
| 240 ;; In case comment-end has changed since last time. | |
| 241 (string-match comment-end-skip comment-end)) | |
| 1333 | 242 (let ((ce (if (string= "" comment-end) "\n" |
| 243 (comment-string-strip comment-end t t)))) | |
| 244 (set (make-local-variable 'comment-end-skip) | |
| 245 ;; We use [ \t] rather than \s- because we don't want to | |
| 246 ;; remove ^L in C mode when uncommenting. | |
| 247 (concat "[ \t]*\\(\\s>" (if comment-quote-nested "" "+") | |
| 248 "\\|" (regexp-quote (substring ce 0 1)) | |
| 249 (if (and comment-quote-nested (<= (length ce) 1)) "" "+") | |
| 250 (regexp-quote (substring ce 1)) | |
| 251 "\\)")))))) | |
| 2511 | 252 |
| 1333 | 253 (defun comment-quote-re (str unp) |
| 254 (concat (regexp-quote (substring str 0 1)) | |
| 255 "\\\\" (if unp "+" "*") | |
| 256 (regexp-quote (substring str 1)))) | |
| 257 | |
| 258 (defun comment-quote-nested (cs ce unp) | |
| 259 "Quote or unquote nested comments. | |
| 260 If UNP is non-nil, unquote nested comment markers." | |
| 261 (setq cs (comment-string-strip cs t t)) | |
| 262 (setq ce (comment-string-strip ce t t)) | |
| 263 (when (and comment-quote-nested (> (length ce) 0)) | |
| 264 (let ((re (concat (comment-quote-re ce unp) | |
| 265 "\\|" (comment-quote-re cs unp)))) | |
| 266 (goto-char (point-min)) | |
| 267 (while (re-search-forward re nil t) | |
| 268 (goto-char (match-beginning 0)) | |
| 269 (forward-char 1) | |
| 270 (if unp (delete-char 1) (insert "\\")) | |
|
5366
f00192e1cd49
Examining the result of #'length: `eql', not `=', it's better style & cheaper
Aidan Kehoe <kehoea@parhasard.net>
parents:
4435
diff
changeset
|
271 (when (eql (length ce) 1) |
| 1333 | 272 ;; If the comment-end is a single char, adding a \ after that |
| 273 ;; "first" char won't deactivate it, so we turn such a CE | |
| 274 ;; into !CS. I.e. for pascal, we turn } into !{ | |
| 275 (if (not unp) | |
| 276 (when (string= (match-string 0) ce) | |
| 277 (replace-match (concat "!" cs) t t)) | |
| 278 (when (and (< (point-min) (match-beginning 0)) | |
| 279 (string= (buffer-substring (1- (match-beginning 0)) | |
| 280 (1- (match-end 0))) | |
| 281 (concat "!" cs))) | |
| 282 (backward-char 2) | |
| 283 (delete-char (- (match-end 0) (match-beginning 0))) | |
| 284 (insert ce)))))))) | |
| 285 | |
| 286 ;;;; | |
| 287 ;;;; Navigation | |
| 288 ;;;; | |
| 289 | |
| 290 (defun comment-search-forward (limit &optional noerror) | |
| 291 "Find a comment start between point and LIMIT. | |
| 292 Moves point to inside the comment and returns the position of the | |
| 293 comment-starter. If no comment is found, moves point to LIMIT | |
| 294 and raises an error or returns nil of NOERROR is non-nil." | |
| 295 (if (not comment-use-syntax) | |
| 296 (if (re-search-forward comment-start-skip limit noerror) | |
| 297 (or (match-end 1) (match-beginning 0)) | |
| 298 (goto-char limit) | |
| 299 (unless noerror (error "No comment"))) | |
| 300 (let* ((pt (point)) | |
| 301 ;; Assume (at first) that pt is outside of any string. | |
| 302 (s (parse-partial-sexp pt (or limit (point-max)) nil nil nil t))) | |
| 303 (when (and (nth 8 s) (nth 3 s)) | |
| 304 ;; The search ended inside a string. Try to see if it | |
| 305 ;; works better when we assume that pt is inside a string. | |
| 306 (setq s (parse-partial-sexp | |
| 307 pt (or limit (point-max)) nil nil | |
| 308 (list nil nil nil (nth 3 s) nil nil nil nil) | |
| 309 t))) | |
| 310 (if (not (and (nth 8 s) (not (nth 3 s)))) | |
| 311 (unless noerror (error "No comment")) | |
| 312 ;; We found the comment. | |
| 313 (let ((pos (point)) | |
| 314 (start (nth 8 s)) | |
| 315 (bol (line-beginning-position)) | |
| 316 (end nil)) | |
| 317 (while (and (null end) (>= (point) bol)) | |
| 318 (if (looking-at comment-start-skip) | |
| 319 (setq end (min (or limit (point-max)) (match-end 0))) | |
| 320 (backward-char))) | |
| 321 (goto-char (or end pos)) | |
| 322 start))))) | |
| 323 | |
| 324 (defun comment-search-backward (&optional limit noerror) | |
| 325 "Find a comment start between LIMIT and point. | |
| 326 Moves point to inside the comment and returns the position of the | |
| 327 comment-starter. If no comment is found, moves point to LIMIT | |
| 328 and raises an error or returns nil of NOERROR is non-nil." | |
| 329 ;; FIXME: If a comment-start appears inside a comment, we may erroneously | |
| 330 ;; stop there. This can be rather bad in general, but since | |
| 331 ;; comment-search-backward is only used to find the comment-column (in | |
| 332 ;; comment-set-column) and to find the comment-start string (via | |
| 333 ;; comment-beginning) in indent-new-comment-line, it should be harmless. | |
| 334 (if (not (re-search-backward comment-start-skip limit t)) | |
| 335 (unless noerror (error "No comment")) | |
| 336 (beginning-of-line) | |
| 337 (let* ((end (match-end 0)) | |
| 338 (cs (comment-search-forward end t)) | |
| 339 (pt (point))) | |
| 340 (if (not cs) | |
| 341 (progn (beginning-of-line) | |
| 342 (comment-search-backward limit noerror)) | |
| 343 (while (progn (goto-char cs) | |
| 344 (comment-forward) | |
| 345 (and (< (point) end) | |
| 346 (setq cs (comment-search-forward end t)))) | |
| 347 (setq pt (point))) | |
| 348 (goto-char pt) | |
| 349 cs)))) | |
| 350 | |
| 351 (defun comment-beginning () | |
| 352 "Find the beginning of the enclosing comment. | |
| 353 Returns nil if not inside a comment, else moves point and returns | |
| 354 the same as `comment-search-forward'." | |
| 355 ;; HACK ATTACK! | |
| 356 ;; We should really test `in-string-p' but that can be expensive. | |
| 357 (unless (eq (get-text-property (point) 'face) 'font-lock-string-face) | |
| 358 (let ((pt (point)) | |
| 359 (cs (comment-search-backward nil t))) | |
| 360 (when cs | |
| 361 (if (save-excursion | |
| 362 (goto-char cs) | |
| 363 (and | |
| 364 ;; For modes where comment-start and comment-end are the same, | |
| 365 ;; the search above may have found a `ce' rather than a `cs'. | |
| 366 (or (not (looking-at comment-end-skip)) | |
| 367 ;; Maybe font-lock knows that it's a `cs'? | |
| 368 (eq (get-text-property (match-end 0) 'face) | |
| 369 'font-lock-comment-face) | |
| 370 (unless (eq (get-text-property (point) 'face) | |
| 371 'font-lock-comment-face) | |
| 372 ;; Let's assume it's a `cs' if we're on the same line. | |
| 373 (>= (line-end-position) pt))) | |
| 374 ;; Make sure that PT is not past the end of the comment. | |
| 375 (if (comment-forward 1) (> (point) pt) (eobp)))) | |
| 376 cs | |
| 377 (goto-char pt) | |
| 378 nil))))) | |
| 379 | |
| 380 (defun comment-forward (&optional n) | |
| 381 "Skip forward over N comments. | |
| 382 Just like `forward-comment' but only for positive N | |
| 383 and can use regexps instead of syntax." | |
| 384 (setq n (or n 1)) | |
| 385 (if (< n 0) (error "No comment-backward") | |
| 386 (if comment-use-syntax (forward-comment n) | |
| 387 (while (> n 0) | |
| 388 (setq n | |
| 389 (if (or (forward-comment 1) | |
| 390 (and (looking-at comment-start-skip) | |
| 391 (goto-char (match-end 0)) | |
| 392 (re-search-forward comment-end-skip nil 'move))) | |
| 393 (1- n) -1))) | |
| 394 (= n 0)))) | |
| 395 | |
| 396 (defun comment-enter-backward () | |
| 397 "Move from the end of a comment to the end of its content. | |
| 398 Point is assumed to be just at the end of a comment." | |
| 399 (if (bolp) | |
| 400 ;; comment-end = "" | |
| 401 (progn (backward-char) (skip-syntax-backward " ")) | |
| 402 (let ((end (point))) | |
| 403 (beginning-of-line) | |
| 404 (save-restriction | |
| 405 (narrow-to-region (point) end) | |
| 406 (if (re-search-forward (concat comment-end-skip "\\'") nil t) | |
| 407 (goto-char (match-beginning 0)) | |
| 408 ;; comment-end-skip not found probably because it was not set right. | |
| 409 ;; Since \\s> should catch the single-char case, we'll blindly | |
| 410 ;; assume we're at the end of a two-char comment-end. | |
| 411 (goto-char (point-max)) | |
| 412 (backward-char 2) | |
| 413 (skip-chars-backward (string (char-after))) | |
| 414 (skip-syntax-backward " ")))))) | |
| 415 | |
| 416 ;;;; | |
| 417 ;;;; Commands | |
| 418 ;;;; | |
| 419 | |
| 420 | |
| 421 ;; #### XEmacs had this: in place of just (current-column) | |
| 422 ; (defconst comment-indent-function | |
| 423 ; ;; XEmacs - add at least one space after the end of the text on the | |
| 424 ; ;; current line... | |
| 425 ; (lambda () | |
| 426 ; (save-excursion | |
| 427 ; (beginning-of-line) | |
| 428 ; (let ((eol (save-excursion (end-of-line) (point)))) | |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
429 ; (and comment-start-skip |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
430 ; (re-search-forward comment-start-skip eol t) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
431 ; (setq eol (match-beginning 0))) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
432 ; (goto-char eol) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
433 ; (skip-chars-backward " \t") |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
434 ; (max comment-column (1+ (current-column)))))) |
| 1333 | 435 ; "Function to compute desired indentation for a comment. |
| 436 ; This function is called with no args with point at the beginning of | |
| 437 ; the comment's starting delimiter.") | |
| 438 | |
| 439 (defun comment-indent-default () | |
| 440 "Default for `comment-indent-function'." | |
| 441 (if (and (looking-at "\\s<\\s<\\(\\s<\\)?") | |
| 442 (or (match-end 1) (/= (current-column) (current-indentation)))) | |
| 443 0 | |
| 444 (when (or (/= (current-column) (current-indentation)) | |
| 445 (and (> comment-add 0) (looking-at "\\s<\\S<"))) | |
| 446 comment-column))) | |
| 447 | |
| 448 (defun comment-indent (&optional continue) | |
| 449 "Indent this line's comment to comment column, or insert an empty comment. | |
| 450 If CONTINUE is non-nil, use the `comment-continue' markers if any. | |
| 451 Comments starting in column 0 are not moved." | |
| 452 (interactive "*") | |
| 453 (comment-normalize-vars) | |
| 454 (let* ((empty (save-excursion (beginning-of-line) | |
| 455 (looking-at "[ \t]*$"))) | |
| 456 (starter (or (and continue comment-continue) | |
| 457 (and empty block-comment-start) comment-start)) | |
| 458 (ender (or (and continue comment-continue "") | |
| 459 (and empty block-comment-end) comment-end))) | |
| 460 (unless starter (error "No comment syntax defined")) | |
| 461 (beginning-of-line) | |
| 462 (let* ((eolpos (line-end-position)) | |
| 463 (begpos (comment-search-forward eolpos t)) | |
| 464 cpos indent) | |
| 465 ;; An existing comment? | |
| 2511 | 466 (if begpos |
| 467 (progn | |
| 468 (if (and (not (looking-at "[\t\n ]")) | |
| 469 (looking-at comment-end-skip)) | |
| 470 ;; The comment is empty and we have skipped all its space | |
| 471 ;; and landed right before the comment-ender: | |
| 472 ;; Go back to the middle of the space. | |
| 473 (forward-char (/ (skip-chars-backward " \t") -2))) | |
| 474 (setq cpos (point-marker))) | |
| 1333 | 475 ;; If none, insert one. |
| 476 (save-excursion | |
| 477 ;; Some comment-indent-function insist on not moving comments that | |
| 478 ;; are in column 0, so we first go to the likely target column. | |
| 479 (indent-to comment-column) | |
| 480 (setq begpos (point)) | |
| 2511 | 481 ;; Ensure there's a space before the comment for things |
| 482 ;; like sh where it matters (as well as being neater). | |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
483 ;; ... but unless we're at the beginning of a line -- dvl |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
484 (unless (or (bolp) (eq ?\ (char-syntax (char-before)))) |
| 2511 | 485 (insert ?\ )) |
| 1333 | 486 (insert starter) |
| 487 (setq cpos (point-marker)) | |
| 488 (insert ender))) | |
| 489 (goto-char begpos) | |
| 490 ;; Compute desired indent. | |
| 491 (setq indent (save-excursion (funcall comment-indent-function))) | |
| 492 (if (not indent) | |
| 2511 | 493 ;; comment-indent-function refuses: delegate to indent. |
| 1333 | 494 (indent-according-to-mode) |
| 495 ;; Avoid moving comments past the fill-column. | |
| 496 (unless (save-excursion (skip-chars-backward " \t") (bolp)) | |
| 497 (setq indent | |
| 498 (min indent | |
| 499 (+ (current-column) | |
| 2511 | 500 (- (or comment-fill-column fill-column) |
| 1333 | 501 (save-excursion (end-of-line) (current-column))))))) |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
502 ;; XEmacs change: Preserve indentation of comments starting in |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
503 ;; column 0, as documented. |
| 2511 | 504 (unless (or (= (current-column) 0) (= (current-column) indent)) |
| 1333 | 505 ;; If that's different from current, change it. |
| 2511 | 506 (delete-region (point) (progn (skip-chars-backward " \t") (point))) |
| 1333 | 507 (indent-to (if (bolp) indent |
| 508 (max indent (1+ (current-column))))))) | |
| 509 (goto-char cpos) | |
| 510 (set-marker cpos nil)))) | |
| 511 | |
| 512 (defun comment-set-column (arg) | |
| 513 "Set the comment column based on point. | |
| 514 With no ARG, set the comment column to the current column. | |
| 515 With just minus as arg, kill any comment on this line. | |
| 516 With any other arg, set comment column to indentation of the previous comment | |
| 517 and then align or create a comment on this line at that column." | |
| 518 (interactive "P") | |
| 519 (cond | |
| 520 ((eq arg '-) (comment-kill nil)) | |
| 521 (arg | |
| 522 (save-excursion | |
| 523 (beginning-of-line) | |
| 524 (comment-search-backward) | |
| 525 (beginning-of-line) | |
| 526 (goto-char (comment-search-forward (line-end-position))) | |
| 527 (setq comment-column (current-column)) | |
| 528 (lmessage 'command "Comment column set to %d" comment-column)) | |
| 529 (comment-indent)) | |
| 530 (t (setq comment-column (current-column)) | |
| 531 (lmessage 'command "Comment column set to %d" comment-column)))) | |
| 532 | |
| 533 (defun comment-kill (arg) | |
| 534 "Kill the comment on this line, if any. | |
| 535 With prefix ARG, kill comments on that many lines starting with this one." | |
| 536 ;; XEmacs change: add * | |
| 537 (interactive "*P") | |
| 538 (dotimes (_ (prefix-numeric-value arg)) | |
| 539 (save-excursion | |
| 540 (beginning-of-line) | |
| 541 (let ((cs (comment-search-forward (line-end-position) t))) | |
| 542 (when cs | |
| 543 (goto-char cs) | |
| 544 (skip-syntax-backward " ") | |
| 545 (setq cs (point)) | |
| 546 (comment-forward) | |
| 547 (kill-region cs (if (bolp) (1- (point)) (point))) | |
| 548 (indent-according-to-mode)))) | |
| 549 (if arg (forward-line 1)))) | |
| 550 | |
| 551 (defun comment-padright (str &optional n) | |
| 552 "Construct a string composed of STR plus `comment-padding'. | |
| 553 It also adds N copies of the last non-whitespace chars of STR. | |
| 554 If STR already contains padding, the corresponding amount is | |
| 555 ignored from `comment-padding'. | |
| 556 N defaults to 0. | |
| 557 If N is `re', a regexp is returned instead, that would match | |
| 558 the string for any N." | |
| 559 (setq n (or n 0)) | |
| 560 (when (and (stringp str) (not (string= "" str))) | |
| 561 ;; Separate the actual string from any leading/trailing padding | |
| 562 (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str) | |
| 563 (let ((s (match-string 1 str)) ;actual string | |
| 564 (lpad (substring str 0 (match-beginning 1))) ;left padding | |
| 565 (rpad (concat (substring str (match-end 1)) ;original right padding | |
| 566 (substring comment-padding ;additional right padding | |
| 567 (min (- (match-end 0) (match-end 1)) | |
| 568 (length comment-padding))))) | |
| 569 ;; We can only duplicate C if the comment-end has multiple chars | |
| 570 ;; or if comments can be nested, else the comment-end `}' would | |
| 571 ;; be turned into `}}}' where only the first ends the comment | |
| 572 ;; and the rest becomes bogus junk. | |
| 573 (multi (not (and comment-quote-nested | |
| 574 ;; comment-end is a single char | |
| 575 (string-match "\\`\\s-*\\S-\\s-*\\'" comment-end))))) | |
| 576 (if (not (symbolp n)) | |
| 577 (concat lpad s (when multi (make-string n (aref str (1- (match-end 1))))) rpad) | |
| 578 ;; construct a regexp that would match anything from just S | |
| 579 ;; to any possible output of this function for any N. | |
|
5655
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
580 (labels |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
581 ((regexp-quote-with-? (c) (concat (regexp-quote (string c)) "?"))) |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
582 (concat (mapconcat #'regexp-quote-with-? |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
583 lpad "") ;padding is not required |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
584 (regexp-quote s) |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
585 (when multi "+") ;the last char of S might be repeated |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
586 (mapconcat #'regexp-quote-with-? |
|
b7ae5f44b950
Remove some redundant functions, change others to labels, lisp/
Aidan Kehoe <kehoea@parhasard.net>
parents:
5490
diff
changeset
|
587 rpad ""))))))) ;padding is not required |
| 1333 | 588 |
| 589 (defun comment-padleft (str &optional n) | |
| 590 "Construct a string composed of `comment-padding' plus STR. | |
| 591 It also adds N copies of the first non-whitespace chars of STR. | |
| 592 If STR already contains padding, the corresponding amount is | |
| 593 ignored from `comment-padding'. | |
| 594 N defaults to 0. | |
| 595 If N is `re', a regexp is returned instead, that would match | |
| 596 the string for any N." | |
| 597 (setq n (or n 0)) | |
| 598 (when (and (stringp str) (not (string= "" str))) | |
| 599 ;; Only separate the left pad because we assume there is no right pad. | |
| 600 (string-match "\\`\\s-*" str) | |
| 601 (let ((s (substring str (match-end 0))) | |
| 602 (pad (concat (substring comment-padding | |
| 603 (min (- (match-end 0) (match-beginning 0)) | |
| 604 (length comment-padding))) | |
| 605 (match-string 0 str))) | |
| 606 (c (aref str (match-end 0))) ;the first non-space char of STR | |
| 607 ;; We can only duplicate C if the comment-end has multiple chars | |
| 608 ;; or if comments can be nested, else the comment-end `}' would | |
| 609 ;; be turned into `}}}' where only the first ends the comment | |
| 610 ;; and the rest becomes bogus junk. | |
| 611 (multi (not (and comment-quote-nested | |
| 612 ;; comment-end is a single char | |
| 613 (string-match "\\`\\s-*\\S-\\s-*\\'" comment-end))))) | |
| 614 (if (not (symbolp n)) | |
| 615 (concat pad (when multi (make-string n c)) s) | |
| 616 ;; Construct a regexp that would match anything from just S | |
| 617 ;; to any possible output of this function for any N. | |
| 618 ;; We match any number of leading spaces because this regexp will | |
| 619 ;; be used for uncommenting where we might want to remove | |
| 620 ;; uncomment markers with arbitrary leading space (because | |
| 621 ;; they were aligned). | |
| 622 (concat "\\s-*" | |
| 623 (if multi (concat (regexp-quote (string c)) "*")) | |
| 624 (regexp-quote s)))))) | |
| 625 | |
| 626 (defun uncomment-region (beg end &optional arg) | |
| 2511 | 627 "Uncomment each line in the BEG .. END region. |
| 1333 | 628 The numeric prefix ARG can specify a number of chars to remove from the |
| 629 comment markers." | |
| 630 (interactive "*r\nP") | |
| 631 (comment-normalize-vars) | |
| 632 (if (> beg end) (let (mid) (setq mid beg beg end end mid))) | |
| 633 (save-excursion | |
| 634 (goto-char beg) | |
| 635 (setq end (copy-marker end)) | |
| 636 | |
| 2511 | 637 (let* ((numarg (prefix-numeric-value arg)) |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
638 (ccs comment-continue) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
639 (srei (comment-padright ccs 're)) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
640 (sre (and srei (concat "^\\s-*?\\(" srei "\\)"))) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
641 spt) |
| 1333 | 642 (while (and (< (point) end) |
| 643 (setq spt (comment-search-forward end t))) | |
| 2511 | 644 (let ((ipt (point)) |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
645 ;; Find the end of the comment. |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
646 (ept (progn |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
647 (goto-char spt) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
648 (unless (comment-forward) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
649 (error "Can't find the comment end")) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
650 (point))) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
651 (box nil) |
|
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
652 (box-equal nil)) ;Whether we might be using `=' for boxes. |
| 1333 | 653 (save-restriction |
| 654 (narrow-to-region spt ept) | |
| 2511 | 655 |
| 1333 | 656 ;; Remove the comment-start. |
| 657 (goto-char ipt) | |
| 658 (skip-syntax-backward " ") | |
| 659 ;; A box-comment starts with a looong comment-start marker. | |
| 2511 | 660 (when (and (or (and (= (- (point) (point-min)) 1) |
| 661 (setq box-equal t) | |
| 662 (looking-at "=\\{7\\}") | |
| 663 (not (eq (char-before (point-max)) ?\n)) | |
| 664 (skip-chars-forward "=")) | |
| 665 (> (- (point) (point-min) (length comment-start)) 7)) | |
| 666 (> (count-lines (point-min) (point-max)) 2)) | |
| 1333 | 667 (setq box t)) |
| 668 (when (looking-at (regexp-quote comment-padding)) | |
| 669 (goto-char (match-end 0))) | |
| 670 (when (and sre (looking-at (concat "\\s-*\n\\s-*" srei))) | |
| 671 (goto-char (match-end 0))) | |
| 672 (if (null arg) (delete-region (point-min) (point)) | |
| 673 (skip-syntax-backward " ") | |
| 674 (delete-char (- numarg))) | |
| 675 | |
| 676 ;; Remove the end-comment (and leading padding and such). | |
| 677 (goto-char (point-max)) (comment-enter-backward) | |
| 678 ;; Check for special `=' used sometimes in comment-box. | |
| 2511 | 679 (when (and box-equal (not (eq (char-before (point-max)) ?\n))) |
| 1333 | 680 (let ((pos (point))) |
| 681 ;; skip `=' but only if there are at least 7. | |
| 682 (when (> (skip-chars-backward "=") -7) (goto-char pos)))) | |
| 683 (unless (looking-at "\\(\n\\|\\s-\\)*\\'") | |
| 684 (when (and (bolp) (not (bobp))) (backward-char)) | |
| 685 (if (null arg) (delete-region (point) (point-max)) | |
| 686 (skip-syntax-forward " ") | |
| 687 (delete-char numarg))) | |
| 688 | |
| 689 ;; Unquote any nested end-comment. | |
| 690 (comment-quote-nested comment-start comment-end t) | |
| 691 | |
| 692 ;; Eliminate continuation markers as well. | |
| 693 (when sre | |
| 694 (let* ((cce (comment-string-reverse (or comment-continue | |
| 695 comment-start))) | |
| 696 (erei (and box (comment-padleft cce 're))) | |
| 697 (ere (and erei (concat "\\(" erei "\\)\\s-*$")))) | |
| 698 (goto-char (point-min)) | |
| 699 (while (progn | |
| 700 (if (and ere (re-search-forward | |
| 701 ere (line-end-position) t)) | |
| 702 (replace-match "" t t nil (if (match-end 2) 2 1)) | |
| 703 (setq ere nil)) | |
| 704 (forward-line 1) | |
| 705 (re-search-forward sre (line-end-position) t)) | |
| 706 (replace-match "" t t nil (if (match-end 2) 2 1))))) | |
| 2116 | 707 ;; Go to the end for the next comment. |
| 1333 | 708 (goto-char (point-max))))) |
| 709 (set-marker end nil)))) | |
| 710 | |
| 711 (defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) | |
| 712 "Make the leading and trailing extra lines. | |
| 713 This is used for `extra-line' style (or `box' style if BLOCK is specified)." | |
| 714 (let ((eindent 0)) | |
| 715 (if (not block) | |
| 716 ;; Try to match CS and CE's content so they align aesthetically. | |
| 717 (progn | |
| 718 (setq ce (comment-string-strip ce t t)) | |
| 719 (when (string-match "\\(.+\\).*\n\\(.*?\\)\\1" (concat ce "\n" cs)) | |
| 720 (setq eindent | |
| 721 (max (- (match-end 2) (match-beginning 2) (match-beginning 0)) | |
| 722 0)))) | |
| 723 ;; box comment | |
| 724 (let* ((width (- max-indent min-indent)) | |
| 725 (s (concat cs "a=m" cce)) | |
| 726 (e (concat ccs "a=m" ce)) | |
| 727 (c (if (string-match ".*\\S-\\S-" cs) | |
| 2511 | 728 (aref cs (1- (match-end 0))) |
| 729 (if (and (equal comment-end "") (string-match ".*\\S-" cs)) | |
| 730 (aref cs (1- (match-end 0))) ?=))) | |
| 731 (re "\\s-*a=m\\s-*") | |
| 732 ; Huh? (_ (string-match re s)) | |
| 733 (lcs (length cs)) | |
| 1333 | 734 (fill |
| 735 (make-string (+ width (- (match-end 0) | |
| 2511 | 736 (match-beginning 0) lcs 3)) c))) |
| 1333 | 737 (setq cs (replace-match fill t t s)) |
| 2511 | 738 (when (and (not (string-match comment-start-skip cs)) |
| 739 (string-match "a=m" s)) | |
| 740 ;; The whitespace around CS cannot be ignored: put it back. | |
| 741 (setq re "a=m") | |
| 742 (setq fill (make-string (- width lcs) c)) | |
| 743 (setq cs (replace-match fill t t s))) | |
| 744 (string-match re e) | |
| 1333 | 745 (setq ce (replace-match fill t t e)))) |
| 746 (cons (concat cs "\n" (make-string min-indent ? ) ccs) | |
| 747 (concat cce "\n" (make-string (+ min-indent eindent) ? ) ce)))) | |
| 748 | |
| 749 (defmacro comment-with-narrowing (beg end &rest body) | |
| 750 "Execute BODY with BEG..END narrowing. | |
| 751 Space is added (and then removed) at the beginning for the text's | |
| 752 indentation to be kept as it was before narrowing." | |
| 2511 | 753 (declare (debug t) (indent 2)) |
| 1333 | 754 (let ((bindent (make-symbol "bindent"))) |
| 755 `(let ((,bindent (save-excursion (goto-char beg) (current-column)))) | |
| 756 (save-restriction | |
| 757 (narrow-to-region beg end) | |
| 758 (goto-char (point-min)) | |
| 759 (insert (make-string ,bindent ? )) | |
| 760 (prog1 | |
| 761 (progn ,@body) | |
| 762 ;; remove the bindent | |
| 763 (save-excursion | |
| 764 (goto-char (point-min)) | |
| 765 (when (looking-at " *") | |
| 766 (let ((n (min (- (match-end 0) (match-beginning 0)) ,bindent))) | |
| 767 (delete-char n) | |
| 768 (setq ,bindent (- ,bindent n)))) | |
| 769 (end-of-line) | |
| 770 (let ((e (point))) | |
| 771 (beginning-of-line) | |
| 772 (while (and (> ,bindent 0) (re-search-forward " *" e t)) | |
| 773 (let ((n (min ,bindent (- (match-end 0) (match-beginning 0) 1)))) | |
| 774 (goto-char (match-beginning 0)) | |
| 775 (delete-char n) | |
| 776 (setq ,bindent (- ,bindent n))))))))))) | |
| 777 | |
| 778 (defun comment-region-internal (beg end cs ce | |
| 779 &optional ccs cce block lines indent) | |
| 2511 | 780 "Comment region BEG .. END. |
| 1333 | 781 CS and CE are the comment start resp end string. |
| 782 CCS and CCE are the comment continuation strings for the start resp end | |
| 783 of lines (default to CS and CE). | |
| 784 BLOCK indicates that end of lines should be marked with either CCE, CE or CS | |
| 785 \(if CE is empty) and that those markers should be aligned. | |
| 786 LINES indicates that an extra lines will be used at the beginning and end | |
| 787 of the region for CE and CS. | |
| 788 INDENT indicates to put CS and CCS at the current indentation of the region | |
| 789 rather than at left margin." | |
| 790 ;;(assert (< beg end)) | |
| 791 (let ((no-empty t)) | |
| 792 ;; Sanitize CE and CCE. | |
| 793 (if (and (stringp ce) (string= "" ce)) (setq ce nil)) | |
| 794 (if (and (stringp cce) (string= "" cce)) (setq cce nil)) | |
| 795 ;; If CE is empty, multiline cannot be used. | |
| 796 (unless ce (setq ccs nil cce nil)) | |
| 797 ;; Should we mark empty lines as well ? | |
| 798 (if (or ccs block lines) (setq no-empty nil)) | |
| 799 ;; Make sure we have end-markers for BLOCK mode. | |
| 800 (when block (unless ce (setq ce (comment-string-reverse cs)))) | |
| 801 ;; If BLOCK is not requested, we don't need CCE. | |
| 802 (unless block (setq cce nil)) | |
| 803 ;; Continuation defaults to the same as CS and CE. | |
| 804 (unless ccs (setq ccs cs cce ce)) | |
| 2511 | 805 |
| 1333 | 806 (save-excursion |
| 807 (goto-char end) | |
| 808 ;; If the end is not at the end of a line and the comment-end | |
| 809 ;; is implicit (i.e. a newline), explicitly insert a newline. | |
| 810 (unless (or ce (eolp)) (insert "\n") (indent-according-to-mode)) | |
| 811 (comment-with-narrowing beg end | |
| 812 (let ((min-indent (point-max)) | |
| 813 (max-indent 0)) | |
| 814 (goto-char (point-min)) | |
| 815 ;; Quote any nested comment marker | |
| 816 (comment-quote-nested comment-start comment-end nil) | |
| 817 | |
| 818 ;; Loop over all lines to find the needed indentations. | |
| 819 (goto-char (point-min)) | |
| 820 (while | |
| 821 (progn | |
| 822 (unless (looking-at "[ \t]*$") | |
| 823 (setq min-indent (min min-indent (current-indentation)))) | |
| 824 (end-of-line) | |
| 825 (setq max-indent (max max-indent (current-column))) | |
| 826 (not (or (eobp) (progn (forward-line) nil))))) | |
| 2511 | 827 |
| 1333 | 828 ;; Inserting ccs can change max-indent by (1- tab-width). |
| 829 (setq max-indent | |
| 830 (+ max-indent (max (length cs) (length ccs)) tab-width -1)) | |
| 831 (unless indent (setq min-indent 0)) | |
| 832 | |
| 833 ;; make the leading and trailing lines if requested | |
| 834 (when lines | |
| 835 (let ((csce | |
| 836 (comment-make-extra-lines | |
| 837 cs ce ccs cce min-indent max-indent block))) | |
| 838 (setq cs (car csce)) | |
| 839 (setq ce (cdr csce)))) | |
| 2511 | 840 |
| 1333 | 841 (goto-char (point-min)) |
| 842 ;; Loop over all lines from BEG to END. | |
| 843 (while | |
| 844 (progn | |
| 845 (unless (and no-empty (looking-at "[ \t]*$")) | |
| 846 (move-to-column min-indent t) | |
| 847 (insert cs) (setq cs ccs) ;switch to CCS after the first line | |
| 848 (end-of-line) | |
| 849 (if (eobp) (setq cce ce)) | |
| 850 (when cce | |
| 851 (when block (move-to-column max-indent t)) | |
| 852 (insert cce))) | |
| 853 (end-of-line) | |
| 854 (not (or (eobp) (progn (forward-line) nil)))))))))) | |
| 855 | |
| 856 (defun comment-region (beg end &optional arg) | |
| 857 "Comment or uncomment each line in the region. | |
| 2511 | 858 With just \\[universal-argument] prefix arg, uncomment each line in region BEG .. END. |
| 1333 | 859 Numeric prefix arg ARG means use ARG comment characters. |
| 860 If ARG is negative, delete that many comment characters instead. | |
| 861 By default, comments start at the left margin, are terminated on each line, | |
| 862 even for syntax in which newline does not end the comment and blank lines | |
| 863 do not get comments. This can be changed with `comment-style'. | |
| 864 | |
| 865 The strings used as comment starts are built from | |
| 866 `comment-start' without trailing spaces and `comment-padding'." | |
| 867 (interactive "*r\nP") | |
| 868 (comment-normalize-vars) | |
| 869 (if (> beg end) (let (mid) (setq mid beg beg end end mid))) | |
| 870 (let* ((numarg (prefix-numeric-value arg)) | |
| 871 (add comment-add) | |
| 872 (style (cdr (assoc comment-style comment-styles))) | |
| 873 (lines (nth 2 style)) | |
| 874 (block (nth 1 style)) | |
| 875 (multi (nth 0 style))) | |
| 876 (save-excursion | |
| 877 ;; we use `chars' instead of `syntax' because `\n' might be | |
| 878 ;; of end-comment syntax rather than of whitespace syntax. | |
| 879 ;; sanitize BEG and END | |
| 880 (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line) | |
| 881 (setq beg (max beg (point))) | |
| 882 (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line) | |
| 883 (setq end (min end (point))) | |
| 884 (if (>= beg end) (error "Nothing to comment")) | |
| 885 | |
| 886 ;; sanitize LINES | |
| 887 (setq lines | |
| 888 (and | |
| 889 lines ;; multi | |
| 890 (progn (goto-char beg) (beginning-of-line) | |
| 891 (skip-syntax-forward " ") | |
| 892 (>= (point) beg)) | |
| 893 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ") | |
| 894 (<= (point) end)) | |
| 2511 | 895 (or block (not (string= "" comment-end))) |
| 896 (or block (progn (goto-char beg) (search-forward "\n" end t)))))) | |
| 1333 | 897 |
| 898 ;; don't add end-markers just because the user asked for `block' | |
| 899 (unless (or lines (string= "" comment-end)) (setq block nil)) | |
| 900 | |
| 901 (cond | |
| 902 ((consp arg) (uncomment-region beg end)) | |
| 903 ((< numarg 0) (uncomment-region beg end (- numarg))) | |
| 904 (t | |
|
5366
f00192e1cd49
Examining the result of #'length: `eql', not `=', it's better style & cheaper
Aidan Kehoe <kehoea@parhasard.net>
parents:
4435
diff
changeset
|
905 (setq numarg (if (and (null arg) (eql (length comment-start) 1)) |
| 1333 | 906 add (1- numarg))) |
| 907 (comment-region-internal | |
| 908 beg end | |
| 909 (let ((s (comment-padright comment-start numarg))) | |
| 910 (if (string-match comment-start-skip s) s | |
| 911 (comment-padright comment-start))) | |
| 912 (let ((s (comment-padleft comment-end numarg))) | |
| 913 (and s (if (string-match comment-end-skip s) s | |
| 914 (comment-padright comment-end)))) | |
| 915 (if multi (comment-padright comment-continue numarg)) | |
| 916 (if multi (comment-padleft (comment-string-reverse comment-continue) numarg)) | |
| 917 block | |
| 918 lines | |
| 919 (nth 3 style)))))) | |
| 920 | |
| 921 (defun comment-box (beg end &optional arg) | |
| 2511 | 922 "Comment out the BEG .. END region, putting it inside a box. |
| 1333 | 923 The numeric prefix ARG specifies how many characters to add to begin- and |
| 924 end- comment markers additionally to what `comment-add' already specifies." | |
| 925 (interactive "*r\np") | |
| 926 (let ((comment-style (if (cadr (assoc comment-style comment-styles)) | |
| 927 'box-multi 'box))) | |
| 928 (comment-region beg end (+ comment-add arg)))) | |
| 929 | |
| 2511 | 930 |
| 931 (defun comment-or-uncomment-region (beg end &optional arg) | |
| 932 "Call `comment-region', unless the region only consists of comments, | |
| 933 in which case call `uncomment-region'. If a prefix arg is given, it | |
| 934 is passed on to the respective function." | |
| 935 (interactive "*r\nP") | |
| 936 (funcall (if (save-excursion ;; check for already commented region | |
| 937 (goto-char beg) | |
| 938 (comment-forward (point-max)) | |
| 939 (<= end (point))) | |
| 940 'uncomment-region 'comment-region) | |
| 941 beg end arg)) | |
| 942 | |
| 1333 | 943 (defun comment-dwim (arg) |
| 944 "Call the comment command you want (Do What I Mean). | |
| 945 If the region is active and `transient-mark-mode' is on, call | |
| 946 `comment-region' (unless it only consists of comments, in which | |
| 947 case it calls `uncomment-region'). | |
| 948 Else, if the current line is empty, insert a comment and indent it. | |
| 949 Else if a prefix ARG is specified, call `comment-kill'. | |
| 950 Else, call `comment-indent'." | |
| 951 (interactive "*P") | |
| 952 (comment-normalize-vars) | |
| 953 (if (region-active-p) ;mark-active transient-mark-mode) | |
| 2511 | 954 (comment-or-uncomment-region (region-beginning) (region-end) arg) |
| 1333 | 955 (if (save-excursion (beginning-of-line) (not (looking-at "\\s-*$"))) |
| 956 ;; FIXME: If there's no comment to kill on this line and ARG is | |
| 957 ;; specified, calling comment-kill is not very clever. | |
| 958 (if arg (comment-kill (and (integerp arg) arg)) (comment-indent)) | |
| 959 (let ((add (if arg (prefix-numeric-value arg) | |
|
5366
f00192e1cd49
Examining the result of #'length: `eql', not `=', it's better style & cheaper
Aidan Kehoe <kehoea@parhasard.net>
parents:
4435
diff
changeset
|
960 (if (eql (length comment-start) 1) comment-add 0)))) |
| 1333 | 961 ;; Some modes insist on keeping column 0 comment in column 0 |
| 962 ;; so we need to move away from it before inserting the comment. | |
| 963 (indent-according-to-mode) | |
| 964 (insert (comment-padright comment-start add)) | |
| 965 (save-excursion | |
| 966 (unless (string= "" comment-end) | |
| 967 (insert (comment-padleft comment-end add))) | |
| 968 (indent-according-to-mode)))))) | |
| 969 | |
| 970 (defcustom comment-auto-fill-only-comments nil | |
| 971 "Non-nil means to only auto-fill inside comments. | |
| 972 This has no effect in modes that do not define a comment syntax." | |
| 2511 | 973 :type 'boolean) |
| 974 | |
| 975 (defun comment-valid-prefix (prefix compos) | |
| 976 (or | |
| 977 ;; Accept any prefix if the current comment is not EOL-terminated. | |
| 978 (save-excursion (goto-char compos) (comment-forward) (not (bolp))) | |
| 979 ;; Accept any prefix that starts with a comment-start marker. | |
| 980 (string-match (concat "\\`[ \t]*\\(?:" comment-start-skip "\\)") | |
| 981 fill-prefix))) | |
| 1333 | 982 |
| 983 (defun comment-indent-new-line (&optional soft) | |
| 984 "Break line at point and indent, continuing comment if within one. | |
| 985 This indents the body of the continued comment | |
| 986 under the previous comment line. | |
| 987 | |
| 988 This command is intended for styles where you write a comment per line, | |
| 989 starting a new comment (and terminating it if necessary) on each line. | |
| 990 If you want to continue one comment across several lines, use \\[newline-and-indent]. | |
| 991 | |
| 992 If a fill column is specified, it overrides the use of the comment column | |
| 993 or comment indentation. | |
| 994 | |
| 995 The inserted newline is marked hard if variable `use-hard-newlines' is true, | |
| 996 unless optional argument SOFT is non-nil." | |
| 997 (interactive) | |
| 998 (comment-normalize-vars t) | |
| 999 (let (compos comin) | |
| 1000 ;; If we are not inside a comment and we only auto-fill comments, | |
| 1001 ;; don't do anything (unless no comment syntax is defined). | |
| 1002 (unless (and comment-start | |
| 1003 comment-auto-fill-only-comments | |
| 2511 | 1004 (not (interactive-p)) |
| 1333 | 1005 (not (save-excursion |
| 1006 (prog1 (setq compos (comment-beginning)) | |
| 1007 (setq comin (point)))))) | |
| 1008 | |
| 1009 ;; XEmacs: next 3 lines from old version. | |
| 1010 (skip-chars-backward " \t") | |
| 1011 (if (featurep 'mule) | |
| 1012 (declare-fboundp (kinsoku-process))) | |
| 2511 | 1013 |
| 1014 ;; Now we know we should auto-fill. | |
| 1015 ;; Insert the newline before removing empty space so that markers | |
| 1016 ;; get preserved better. | |
| 1333 | 1017 (if soft (insert-and-inherit ?\n) (newline 1)) |
| 2511 | 1018 (save-excursion (forward-char -1) (delete-horizontal-space)) |
| 1019 (delete-horizontal-space) | |
| 1020 | |
| 1021 (if (and fill-prefix (not adaptive-fill-mode)) | |
| 1022 ;; Blindly trust a non-adaptive fill-prefix. | |
| 1333 | 1023 (progn |
| 1024 (indent-to-left-margin) | |
| 2511 | 1025 (insert-before-markers-and-inherit fill-prefix)) |
| 1333 | 1026 |
| 1027 ;;#### jhod: probably need to fix this for kinsoku processing | |
| 1028 ;; If necessary check whether we're inside a comment. | |
| 2511 | 1029 (unless (or compos (null comment-start)) |
| 1333 | 1030 (save-excursion |
| 1031 (backward-char) | |
| 1032 (setq compos (comment-beginning)) | |
| 1033 (setq comin (point)))) | |
| 1034 | |
| 2511 | 1035 (cond |
| 1036 ;; If there's an adaptive prefix, use it unless we're inside | |
| 1037 ;; a comment and the prefix is not a comment starter. | |
| 1038 ((and fill-prefix | |
| 1039 (or (not compos) | |
| 1040 (comment-valid-prefix fill-prefix compos))) | |
| 1041 (indent-to-left-margin) | |
| 1042 (insert-and-inherit fill-prefix)) | |
| 1043 ;; If we're not inside a comment, just try to indent. | |
| 1044 ;; #### XEmacs: the line `(if comcol' was changed as follows. | |
| 1045 ;; I'm leaving it out since who knows if it's applicable any more. | |
| 1046 ;; --ben | |
| 1047 ;; (if (and comcol (not fill-prefix)) ; XEmacs - (ENE) from fa-extras. | |
| 1048 ((not compos) (indent-according-to-mode)) | |
| 1049 (t | |
| 1333 | 1050 (let* ((comment-column |
| 1051 ;; The continuation indentation should be somewhere between | |
| 1052 ;; the current line's indentation (plus 2 for good measure) | |
| 1053 ;; and the current comment's indentation, with a preference | |
| 1054 ;; for comment-column. | |
| 1055 (save-excursion | |
| 2511 | 1056 ;; FIXME: use prev line's info rather than first line's. |
| 1333 | 1057 (goto-char compos) |
| 1058 (min (current-column) (max comment-column | |
| 1059 (+ 2 (current-indentation)))))) | |
| 1060 (comstart (buffer-substring compos comin)) | |
| 1061 (normalp | |
| 1062 (string-match (regexp-quote (comment-string-strip | |
| 1063 comment-start t t)) | |
| 1064 comstart)) | |
| 1065 (comment-end | |
| 1066 (if normalp comment-end | |
| 1067 ;; The comment starter is not the normal comment-start | |
| 1068 ;; so we can't just use comment-end. | |
| 1069 (save-excursion | |
| 1070 (goto-char compos) | |
| 1071 (if (not (comment-forward)) comment-end | |
| 1072 (comment-string-strip | |
| 1073 (buffer-substring | |
| 1074 (save-excursion (comment-enter-backward) (point)) | |
| 1075 (point)) | |
| 1076 nil t))))) | |
| 1077 (comment-start comstart) | |
|
4435
1e2fc51563a5
Fix auto-formatting of comments in auto-fill-mode
Didier Verna <didier@xemacs.org>
parents:
3289
diff
changeset
|
1078 (block-comment-start comment-start) |
| 2511 | 1079 (continuep (or comment-multi-line |
| 1080 (cadr (assoc comment-style comment-styles)))) | |
| 1333 | 1081 ;; Force comment-continue to be recreated from comment-start. |
| 1082 ;; FIXME: wrong if comment-continue was set explicitly! | |
| 2511 | 1083 ;; FIXME: use prev line's continuation if available. |
| 1333 | 1084 (comment-continue nil)) |
| 2511 | 1085 (if (and comment-multi-line (> (length comment-end) 0)) |
| 1086 (indent-according-to-mode) | |
| 1087 (insert-and-inherit ?\n) | |
| 1088 (forward-char -1) | |
| 1089 (comment-indent continuep) | |
| 1090 (save-excursion | |
| 1091 (let ((pt (point))) | |
| 1092 (end-of-line) | |
| 1093 (let ((comend (buffer-substring pt (point)))) | |
| 1094 ;; The 1+ is to make sure we delete the \n inserted above. | |
| 1095 (delete-region pt (1+ (point))) | |
| 1096 (end-of-line 0) | |
| 1097 (insert comend)))))))))))) | |
| 1333 | 1098 |
| 1099 (provide 'newcomment) | |
| 1100 | |
| 1101 ;;; newcomment.el ends here |
