Mercurial > emacs
comparison lisp/format.el @ 90573:858cb33ae39d
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 357-381)
- Merge from gnus--rel--5.10
- Update from CVS
- Merge from erc--emacs--21
* gnus--rel--5.10 (patch 116-122)
- Update from CVS
- Merge from emacs--devo--0
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-98
author | Miles Bader <miles@gnu.org> |
---|---|
date | Thu, 03 Aug 2006 11:45:23 +0000 |
parents | c5406394f567 2d16125405b4 |
children | f1d13e615070 |
comparison
equal
deleted
inserted
replaced
90572:ab9b8d043c39 | 90573:858cb33ae39d |
---|---|
106 format. It is currently unused, but in the future will be shown to | 106 format. It is currently unused, but in the future will be shown to |
107 the user if they ask for more information. | 107 the user if they ask for more information. |
108 | 108 |
109 REGEXP is a regular expression to match against the beginning of the file; | 109 REGEXP is a regular expression to match against the beginning of the file; |
110 it should match only files in that format. Use nil to avoid | 110 it should match only files in that format. Use nil to avoid |
111 matching at all for formats for which this isn't appropriate to | 111 matching at all for formats for which it isn't appropriate to |
112 require explicit encoding/decoding. | 112 require explicit encoding/decoding. |
113 | 113 |
114 FROM-FN is called to decode files in that format; it gets two args, BEGIN | 114 FROM-FN is called to decode files in that format; it takes two args, BEGIN |
115 and END, and can make any modifications it likes, returning the new | 115 and END, and can make any modifications it likes, returning the new |
116 end. It must make sure that the beginning of the file no longer | 116 end. It must make sure that the beginning of the file no longer |
117 matches REGEXP, or else it will get called again. | 117 matches REGEXP, or else it will get called again. |
118 Alternatively, FROM-FN can be a string, which specifies a shell command | 118 Alternatively, FROM-FN can be a string, which specifies a shell command |
119 (including options) to be used as a filter to perform the conversion. | 119 (including options) to be used as a filter to perform the conversion. |
120 | 120 |
121 TO-FN is called to encode a region into that format; it is passed three | 121 TO-FN is called to encode a region into that format; it takes three |
122 arguments: BEGIN, END, and BUFFER. BUFFER is the original buffer that | 122 arguments: BEGIN, END, and BUFFER. BUFFER is the original buffer that |
123 the data being written came from, which the function could use, for | 123 the data being written came from, which the function could use, for |
124 example, to find the values of local variables. TO-FN should either | 124 example, to find the values of local variables. TO-FN should either |
125 return a list of annotations like `write-region-annotate-functions', | 125 return a list of annotations like `write-region-annotate-functions', |
126 or modify the region and return the new end. | 126 or modify the region and return the new end. |
131 TO-FN will not make any changes but will instead return a list of | 131 TO-FN will not make any changes but will instead return a list of |
132 annotations. | 132 annotations. |
133 | 133 |
134 MODE-FN, if specified, is called when visiting a file with that format. | 134 MODE-FN, if specified, is called when visiting a file with that format. |
135 It is called with a single positive argument, on the assumption | 135 It is called with a single positive argument, on the assumption |
136 that it turns on some Emacs mode. | 136 that this would turn on some minor mode. |
137 | 137 |
138 PRESERVE, if non-nil, means that `format-write-file' should not remove | 138 PRESERVE, if non-nil, means that `format-write-file' should not remove |
139 this format from `buffer-file-formats'.") | 139 this format from `buffer-file-formats'.") |
140 | 140 |
141 ;;; Basic Functions (called from Lisp) | 141 ;;; Basic Functions (called from Lisp) |
142 | 142 |
143 (defun format-encode-run-method (method from to &optional buffer) | 143 (defun format-encode-run-method (method from to &optional buffer) |
144 "Translate using function or shell script METHOD the text from FROM to TO. | 144 "Translate using METHOD the text from FROM to TO. |
145 If METHOD is a string, it is a shell command; | 145 If METHOD is a string, it is a shell command (including options); |
146 otherwise, it should be a Lisp function. | 146 otherwise, it should be a Lisp function. |
147 BUFFER should be the buffer that the output originally came from." | 147 BUFFER should be the buffer that the output originally came from." |
148 (if (stringp method) | 148 (if (stringp method) |
149 (let ((error-buff (get-buffer-create "*Format Errors*")) | 149 (let ((error-buff (get-buffer-create "*Format Errors*")) |
150 (coding-system-for-read 'no-conversion) | 150 (coding-system-for-read 'no-conversion) |
162 (switch-to-buffer-other-window error-buff) | 162 (switch-to-buffer-other-window error-buff) |
163 (error "Format encoding failed"))) | 163 (error "Format encoding failed"))) |
164 (funcall method from to buffer))) | 164 (funcall method from to buffer))) |
165 | 165 |
166 (defun format-decode-run-method (method from to &optional buffer) | 166 (defun format-decode-run-method (method from to &optional buffer) |
167 "Decode using function or shell script METHOD the text from FROM to TO. | 167 "Decode using METHOD the text from FROM to TO. |
168 If METHOD is a string, it is a shell command; otherwise, it should be | 168 If METHOD is a string, it is a shell command (including options); otherwise, |
169 a Lisp function. Decoding is done for the given BUFFER." | 169 it should be a Lisp function. Decoding is done for the given BUFFER." |
170 (if (stringp method) | 170 (if (stringp method) |
171 (let ((error-buff (get-buffer-create "*Format Errors*")) | 171 (let ((error-buff (get-buffer-create "*Format Errors*")) |
172 (coding-system-for-write 'no-conversion) | 172 (coding-system-for-write 'no-conversion) |
173 format-alist) | 173 format-alist) |
174 (with-current-buffer error-buff | 174 (with-current-buffer error-buff |
189 (point)) | 189 (point)) |
190 (funcall method from to))) | 190 (funcall method from to))) |
191 | 191 |
192 (defun format-annotate-function (format from to orig-buf format-count) | 192 (defun format-annotate-function (format from to orig-buf format-count) |
193 "Return annotations for writing region as FORMAT. | 193 "Return annotations for writing region as FORMAT. |
194 FORMAT is a symbol naming one of the formats defined in `format-alist', | 194 FORMAT is a symbol naming one of the formats defined in `format-alist'. |
195 it must be a single symbol, not a list like `buffer-file-format'. | 195 It must be a single symbol, not a list like `buffer-file-format'. |
196 FROM and TO delimit the region to be operated on in the current buffer. | 196 FROM and TO delimit the region to be operated on in the current buffer. |
197 ORIG-BUF is the original buffer that the data came from. | 197 ORIG-BUF is the original buffer that the data came from. |
198 | 198 |
199 FORMAT-COUNT is an integer specifying how many times this function has | 199 FORMAT-COUNT is an integer specifying how many times this function has |
200 been called in the process of decoding ORIG-BUF. | 200 been called in the process of decoding ORIG-BUF. |
201 | 201 |
202 This function works like a function on `write-region-annotate-functions': | 202 This function works like a function in `write-region-annotate-functions': |
203 it either returns a list of annotations, or returns with a different buffer | 203 it either returns a list of annotations, or returns with a different buffer |
204 current, which contains the modified text to write. In the latter case, | 204 current, which contains the modified text to write. In the latter case, |
205 this function's value is nil. | 205 this function's value is nil. |
206 | 206 |
207 For most purposes, consider using `format-encode-region' instead." | 207 For most purposes, consider using `format-encode-region' instead." |
242 Second arg LENGTH is the number of characters following point to operate on. | 242 Second arg LENGTH is the number of characters following point to operate on. |
243 If optional third arg VISIT-FLAG is true, set `buffer-file-format' | 243 If optional third arg VISIT-FLAG is true, set `buffer-file-format' |
244 to the reverted list of formats used, and call any mode functions defined | 244 to the reverted list of formats used, and call any mode functions defined |
245 for those formats. | 245 for those formats. |
246 | 246 |
247 Returns the new length of the decoded region. | 247 Return the new length of the decoded region. |
248 | 248 |
249 For most purposes, consider using `format-decode-region' instead." | 249 For most purposes, consider using `format-decode-region' instead." |
250 (let ((mod (buffer-modified-p)) | 250 (let ((mod (buffer-modified-p)) |
251 (begin (point)) | 251 (begin (point)) |
252 (end (+ (point) length))) | 252 (end (+ (point) length))) |
301 ;;; Interactive functions & entry points | 301 ;;; Interactive functions & entry points |
302 ;;; | 302 ;;; |
303 | 303 |
304 (defun format-decode-buffer (&optional format) | 304 (defun format-decode-buffer (&optional format) |
305 "Translate the buffer from some FORMAT. | 305 "Translate the buffer from some FORMAT. |
306 If the format is not specified, this function attempts to guess. | 306 If the format is not specified, attempt a regexp-based guess. |
307 `buffer-file-format' is set to the format used, and any mode-functions | 307 Set `buffer-file-format' to the format used, and call any |
308 for the format are called." | 308 format-specific mode functions." |
309 (interactive | 309 (interactive |
310 (list (format-read "Translate buffer from format (default guess): "))) | 310 (list (format-read "Translate buffer from format (default guess): "))) |
311 (save-excursion | 311 (save-excursion |
312 (goto-char (point-min)) | 312 (goto-char (point-min)) |
313 (format-decode format (buffer-size) t))) | 313 (format-decode format (buffer-size) t))) |
332 buffer-file-format)))) | 332 buffer-file-format)))) |
333 (format-encode-region (point-min) (point-max) format)) | 333 (format-encode-region (point-min) (point-max) format)) |
334 | 334 |
335 (defun format-encode-region (beg end &optional format) | 335 (defun format-encode-region (beg end &optional format) |
336 "Translate the region into some FORMAT. | 336 "Translate the region into some FORMAT. |
337 FORMAT defaults to `buffer-file-format', it is a symbol naming | 337 FORMAT defaults to `buffer-file-format'. It is a symbol naming |
338 one of the formats defined in `format-alist', or a list of such symbols." | 338 one of the formats defined in `format-alist', or a list of such symbols." |
339 (interactive | 339 (interactive |
340 (list (region-beginning) (region-end) | 340 (list (region-beginning) (region-end) |
341 (format-read (format "Translate region to format (default %s): " | 341 (format-read (format "Translate region to format (default %s): " |
342 buffer-file-format)))) | 342 buffer-file-format)))) |
363 "Write current buffer into file FILENAME using some FORMAT. | 363 "Write current buffer into file FILENAME using some FORMAT. |
364 Make buffer visit that file and set the format as the default for future | 364 Make buffer visit that file and set the format as the default for future |
365 saves. If the buffer is already visiting a file, you can specify a directory | 365 saves. If the buffer is already visiting a file, you can specify a directory |
366 name as FILENAME, to write a file of the same old name in that directory. | 366 name as FILENAME, to write a file of the same old name in that directory. |
367 | 367 |
368 If optional third arg CONFIRM is non-nil, this function asks for | 368 If optional third arg CONFIRM is non-nil, ask for confirmation before |
369 confirmation before overwriting an existing file. Interactively, | 369 overwriting an existing file. Interactively, confirmation is required |
370 confirmation is required unless you supply a prefix argument." | 370 unless you supply a prefix argument." |
371 (interactive | 371 (interactive |
372 ;; Same interactive spec as write-file, plus format question. | 372 ;; Same interactive spec as write-file, plus format question. |
373 (let* ((file (if buffer-file-name | 373 (let* ((file (if buffer-file-name |
374 (read-file-name "Write file: " | 374 (read-file-name "Write file: " |
375 nil nil nil nil) | 375 nil nil nil nil) |
408 | 408 |
409 (defun format-insert-file (filename format &optional beg end) | 409 (defun format-insert-file (filename format &optional beg end) |
410 "Insert the contents of file FILENAME using data format FORMAT. | 410 "Insert the contents of file FILENAME using data format FORMAT. |
411 If FORMAT is nil then do not do any format conversion. | 411 If FORMAT is nil then do not do any format conversion. |
412 The optional third and fourth arguments BEG and END specify | 412 The optional third and fourth arguments BEG and END specify |
413 the part of the file to read. | 413 the part (in bytes) of the file to read. |
414 | 414 |
415 The return value is like the value of `insert-file-contents': | 415 The return value is like the value of `insert-file-contents': |
416 a list (ABSOLUTE-FILE-NAME SIZE)." | 416 a list (ABSOLUTE-FILE-NAME SIZE)." |
417 (interactive | 417 (interactive |
418 ;; Same interactive spec as write-file, plus format question. | 418 ;; Same interactive spec as write-file, plus format question. |
445 ;;; | 445 ;;; |
446 | 446 |
447 (defun format-replace-strings (alist &optional reverse beg end) | 447 (defun format-replace-strings (alist &optional reverse beg end) |
448 "Do multiple replacements on the buffer. | 448 "Do multiple replacements on the buffer. |
449 ALIST is a list of (FROM . TO) pairs, which should be proper arguments to | 449 ALIST is a list of (FROM . TO) pairs, which should be proper arguments to |
450 `search-forward' and `replace-match' respectively. | 450 `search-forward' and `replace-match', respectively. |
451 Optional 2nd arg REVERSE, if non-nil, means the pairs are (TO . FROM), so that | 451 Optional second arg REVERSE, if non-nil, means the pairs are (TO . FROM), |
452 you can use the same list in both directions if it contains only literal | 452 so that you can use the same list in both directions if it contains only |
453 strings. | 453 literal strings. |
454 Optional args BEG and END specify a region of the buffer on which to operate." | 454 Optional args BEG and END specify a region of the buffer on which to operate." |
455 (save-excursion | 455 (save-excursion |
456 (save-restriction | 456 (save-restriction |
457 (or beg (setq beg (point-min))) | 457 (or beg (setq beg (point-min))) |
458 (if end (narrow-to-region (point-min) end)) | 458 (if end (narrow-to-region (point-min) end)) |
486 (setcdr p (cdr cons)) | 486 (setcdr p (cdr cons)) |
487 list))) | 487 list))) |
488 | 488 |
489 (defun format-make-relatively-unique (a b) | 489 (defun format-make-relatively-unique (a b) |
490 "Delete common elements of lists A and B, return as pair. | 490 "Delete common elements of lists A and B, return as pair. |
491 Compares using `equal'." | 491 Compare using `equal'." |
492 (let* ((acopy (copy-sequence a)) | 492 (let* ((acopy (copy-sequence a)) |
493 (bcopy (copy-sequence b)) | 493 (bcopy (copy-sequence b)) |
494 (tail acopy)) | 494 (tail acopy)) |
495 (while tail | 495 (while tail |
496 (let ((dup (member (car tail) bcopy)) | 496 (let ((dup (member (car tail) bcopy)) |
500 (setq tail next))) | 500 (setq tail next))) |
501 (cons acopy bcopy))) | 501 (cons acopy bcopy))) |
502 | 502 |
503 (defun format-common-tail (a b) | 503 (defun format-common-tail (a b) |
504 "Given two lists that have a common tail, return it. | 504 "Given two lists that have a common tail, return it. |
505 Compares with `equal', and returns the part of A that is equal to the | 505 Compare with `equal', and return the part of A that is equal to the |
506 equivalent part of B. If even the last items of the two are not equal, | 506 equivalent part of B. If even the last items of the two are not equal, |
507 returns nil." | 507 return nil." |
508 (let ((la (length a)) | 508 (let ((la (length a)) |
509 (lb (length b))) | 509 (lb (length b))) |
510 ;; Make sure they are the same length | 510 ;; Make sure they are the same length |
511 (if (> la lb) | 511 (if (> la lb) |
512 (setq a (nthcdr (- la lb) a)) | 512 (setq a (nthcdr (- la lb) a)) |
523 (while (consp list) | 523 (while (consp list) |
524 (setq list (cdr list))) | 524 (setq list (cdr list))) |
525 (null list))) | 525 (null list))) |
526 | 526 |
527 (defun format-reorder (items order) | 527 (defun format-reorder (items order) |
528 "Arrange ITEMS to following partial ORDER. | 528 "Arrange ITEMS to follow partial ORDER. |
529 Elements of ITEMS equal to elements of ORDER will be rearranged to follow the | 529 Elements of ITEMS equal to elements of ORDER will be rearranged |
530 ORDER. Unmatched items will go last." | 530 to follow the ORDER. Unmatched items will go last." |
531 (if order | 531 (if order |
532 (let ((item (member (car order) items))) | 532 (let ((item (member (car order) items))) |
533 (if item | 533 (if item |
534 (cons (car item) | 534 (cons (car item) |
535 (format-reorder (format-delq-cons item items) | 535 (format-reorder (format-delq-cons item items) |
782 ;; This should probably go somewhere other than format.el. Then again, | 782 ;; This should probably go somewhere other than format.el. Then again, |
783 ;; indent.el has alter-text-property. NOTE: We can also use | 783 ;; indent.el has alter-text-property. NOTE: We can also use |
784 ;; next-single-property-change instead of text-property-not-all, but then | 784 ;; next-single-property-change instead of text-property-not-all, but then |
785 ;; we have to see if we passed TO. | 785 ;; we have to see if we passed TO. |
786 (defun format-property-increment-region (from to prop delta default) | 786 (defun format-property-increment-region (from to prop delta default) |
787 "Over the region between FROM and TO increment property PROP by amount DELTA. | 787 "In the region from FROM to TO increment property PROP by amount DELTA. |
788 DELTA may be negative. If property PROP is nil anywhere | 788 DELTA may be negative. If property PROP is nil anywhere |
789 in the region, it is treated as though it were DEFAULT." | 789 in the region, it is treated as though it were DEFAULT." |
790 (let ((cur from) val newval next) | 790 (let ((cur from) val newval next) |
791 (while cur | 791 (while cur |
792 (setq val (get-text-property cur prop) | 792 (setq val (get-text-property cur prop) |
799 ;;; Encoding | 799 ;;; Encoding |
800 ;;; | 800 ;;; |
801 | 801 |
802 (defun format-insert-annotations (list &optional offset) | 802 (defun format-insert-annotations (list &optional offset) |
803 "Apply list of annotations to buffer as `write-region' would. | 803 "Apply list of annotations to buffer as `write-region' would. |
804 Inserts each element of the given LIST of buffer annotations at its | 804 Insert each element of the given LIST of buffer annotations at its |
805 appropriate place. Use second arg OFFSET if the annotations' locations are | 805 appropriate place. Use second arg OFFSET if the annotations' locations are |
806 not relative to the beginning of the buffer: annotations will be inserted | 806 not relative to the beginning of the buffer: annotations will be inserted |
807 at their location-OFFSET+1 \(ie, the offset is treated as the position of | 807 at their location-OFFSET+1 \(ie, the offset is treated as the position of |
808 the first character in the buffer)." | 808 the first character in the buffer)." |
809 (if (not offset) | 809 (if (not offset) |
823 (cons (if old (list old)) | 823 (cons (if old (list old)) |
824 (if new (list new)))) | 824 (if new (list new)))) |
825 | 825 |
826 (defun format-annotate-region (from to translations format-fn ignore) | 826 (defun format-annotate-region (from to translations format-fn ignore) |
827 "Generate annotations for text properties in the region. | 827 "Generate annotations for text properties in the region. |
828 Searches for changes between FROM and TO, and describes them with a list of | 828 Search for changes between FROM and TO, and describe them with a list of |
829 annotations as defined by alist TRANSLATIONS and FORMAT-FN. IGNORE lists text | 829 annotations as defined by alist TRANSLATIONS and FORMAT-FN. IGNORE lists text |
830 properties not to consider; any text properties that are neither ignored nor | 830 properties not to consider; any text properties that are neither ignored nor |
831 listed in TRANSLATIONS are warned about. | 831 listed in TRANSLATIONS are warned about. |
832 If you actually want to modify the region, give the return value of this | 832 If you actually want to modify the region, give the return value of this |
833 function to `format-insert-annotations'. | 833 function to `format-insert-annotations'. |
964 | 964 |
965 (defun format-annotate-single-property-change (prop old new translations) | 965 (defun format-annotate-single-property-change (prop old new translations) |
966 "Return annotations for property PROP changing from OLD to NEW. | 966 "Return annotations for property PROP changing from OLD to NEW. |
967 These are searched for in the translations alist TRANSLATIONS | 967 These are searched for in the translations alist TRANSLATIONS |
968 (see `format-annotate-region' for the format). | 968 (see `format-annotate-region' for the format). |
969 If NEW does not appear in the list, but there is a default function, then that | 969 If NEW does not appear in the list, but there is a default function, |
970 function is called. | 970 then call that function. |
971 Returns a cons of the form (CLOSE . OPEN) | 971 Return a cons of the form (CLOSE . OPEN) |
972 where CLOSE is a list of annotations to close | 972 where CLOSE is a list of annotations to close |
973 and OPEN is a list of annotations to open. | 973 and OPEN is a list of annotations to open. |
974 | 974 |
975 The annotations in CLOSE and OPEN need not be strings. | 975 The annotations in CLOSE and OPEN need not be strings. |
976 They can be whatever the FORMAT-FN in `format-annotate-region' | 976 They can be whatever the FORMAT-FN in `format-annotate-region' |
1005 new (cdr new))) | 1005 new (cdr new))) |
1006 (format-make-relatively-unique close open))) | 1006 (format-make-relatively-unique close open))) |
1007 (format-annotate-atomic-property-change prop-alist old new))))) | 1007 (format-annotate-atomic-property-change prop-alist old new))))) |
1008 | 1008 |
1009 (defun format-annotate-atomic-property-change (prop-alist old new) | 1009 (defun format-annotate-atomic-property-change (prop-alist old new) |
1010 "Internal function annotate a single property change. | 1010 "Internal function to annotate a single property change. |
1011 PROP-ALIST is the relevant element of a TRANSLATIONS list. | 1011 PROP-ALIST is the relevant element of a TRANSLATIONS list. |
1012 OLD and NEW are the values." | 1012 OLD and NEW are the values." |
1013 (let (num-ann) | 1013 (let (num-ann) |
1014 ;; If old and new values are numbers, | 1014 ;; If old and new values are numbers, |
1015 ;; look for a number in PROP-ALIST. | 1015 ;; look for a number in PROP-ALIST. |