Mercurial > emacs
annotate lisp/=superyank.el @ 837:a8aef92e0025
*** empty log message ***
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 22 Jul 1992 01:36:20 +0000 |
parents | 38b2499cb3e9 |
children | 2cdce064065f |
rev | line source |
---|---|
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
1 ;;; superyank.el --- smart message-yanking code for GNUS |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
2 |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
3 ;; Author: Barry A. Warsaw <warsaw@cme.nist.gov> |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
4 ;; Version: 1.1 |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
5 ;; Last-Modified: 15 Jul 1992 |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
6 ;; Adapted-By: ESR |
814
38b2499cb3e9
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
792
diff
changeset
|
7 ;; Keywords: news |
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
8 |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
9 ;;; Commentary: |
658
7cbd4fcd8b0f
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
10 |
28 | 11 ;; Inserts the message being replied to with various user controlled |
12 ;; citation styles. | |
13 ;; | |
14 | |
15 ;; This file is distributed in the hope that it will be useful, | |
16 ;; but WITHOUT ANY WARRANTY. No author or distributor | |
17 ;; accepts responsibility to anyone for the consequences of using it | |
18 ;; or for whether it serves any particular purpose or works at all, | |
19 ;; unless he says so in writing. Refer to the GNU Emacs General Public | |
20 ;; License for full details. | |
21 | |
22 ;; Everyone is granted permission to copy, modify and redistribute | |
23 ;; this file, but only under the conditions described in the | |
24 ;; GNU Emacs General Public License. A copy of this license is | |
25 ;; supposed to have been given to you along with GNU Emacs so you | |
26 ;; can know your rights and responsibilities. It should be in a | |
27 ;; file named COPYING. Among other things, the copyright notice | |
28 ;; and this notice must be preserved on all copies. | |
29 | |
30 ;; NAME: Barry A. Warsaw USMAIL: National Institute of Standards | |
31 ;; TELE: (301) 975-3460 and Technology (formerly NBS) | |
32 ;; UUCP: {...}!uunet!cme-durer!warsaw Rm. B-124, Bldg. 220 | |
33 ;; ARPA: warsaw@cme.nist.gov Gaithersburg, MD 20899 | |
34 | |
35 ;; Modification history: | |
36 ;; | |
37 ;; modified: 14-Jun-1989 baw (better keymap set procedure, rewrite-headers) | |
38 ;; modified: 12-Jun-1989 baw (added defvar for sy-use-only-preference-p) | |
39 ;; modified: 6-Jun-1989 baw (better sy-rewrite-headers, no kill/yank) | |
40 ;; modified: 5-Jun-1989 baw (requires rnewspost.el) | |
41 ;; modified: 1-Jun-1989 baw (persistent attribution, sy-open-line) | |
42 ;; modified: 31-May-1989 baw (fixed some gnus problems, id'd another) | |
43 ;; modified: 22-May-1989 baw (documentation) | |
44 ;; modified: 8-May-1989 baw (auto filling of regions) | |
45 ;; modified: 1-May-1989 baw (documentation) | |
46 ;; modified: 27-Apr-1989 baw (new preference scheme) | |
47 ;; modified: 24-Apr-1989 baw (remove gnus headers, attrib scheme, cite lines) | |
48 ;; modified: 19-Apr-1989 baw (cite key, fill p, yank region, naming scheme) | |
49 ;; modified: 12-Apr-1989 baw (incorp other mail yank features seen on net) | |
50 ;; created : 16-Feb-1989 baw (mod vanilla fn indent-rigidly mail-yank-original) | |
51 | |
792
45d748a65f24
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
787
diff
changeset
|
52 ;; Though I wrote this package basically from scratch, as an Emacs Lisp |
28 | 53 ;; learning exercise, it was inspired by postings of similar packages to |
54 ;; the gnu.emacs newsgroup over the past month or so. | |
55 ;; | |
56 ;; Here's a brief history of how this package developed: | |
57 ;; | |
58 ;; I as well as others on the net were pretty unhappy about the way emacs | |
59 ;; cited replies with the tab or 4 spaces. It looked ugly and made it hard | |
60 ;; to distinguish between original and cited lines. I hacked on the function | |
61 ;; yank-original to at least give the user the ability to define the citation | |
62 ;; character. I posted this simple hack, and others did as well. The main | |
63 ;; difference between mine and others was that a space was put after the | |
64 ;; citation string on on new citations, but not after previously cited lines: | |
65 ;; | |
66 ;; >> John wrote this originally | |
67 ;; > Jane replied to that | |
68 ;; | |
69 ;; Then Martin Neitzel posted some code that he developed, derived in part | |
70 ;; from code that Ashwin Ram posted previous to that. In Martin's | |
71 ;; posting, he introduced a new, and (IMHO) superior, citation style, | |
72 ;; eliminating nested citations. Yes, I wanted to join the Small-But- | |
73 ;; Growing-Help-Stamp-Out-Nested-Citation-Movement! You should too. | |
74 ;; | |
75 ;; But Martin's code simply asks the user for the citation string (here | |
76 ;; after called the `attribution' string), and I got to thinking, it wouldn't | |
77 ;; be that difficult to automate that part. So I started hacking this out. | |
78 ;; It proved to be not as simple as I first thought. But anyway here it | |
79 ;; is. See the wish list below for future plans (if I have time). | |
80 ;; | |
81 ;; Type "C-h f mail-yank-original" after this package is loaded to get a | |
82 ;; description of what it does and the variables that control it. | |
83 ;; | |
84 ;; ====================================================================== | |
85 ;; | |
86 ;; Changes wish list | |
87 ;; | |
88 ;; 1) C-x C-s yanks a region from the RMAIL buffer instead of the | |
89 ;; whole buffer | |
90 ;; | |
91 ;; 2) reparse nested citations to try to recast as non-nested citations | |
92 ;; perhaps by checking the References: line | |
93 ;; | |
787
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
94 |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
95 ;;; Code: |
3cece0106722
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
96 |
28 | 97 ;; ====================================================================== |
98 ;; | |
99 ;; require and provide features | |
100 ;; | |
101 (require 'sendmail) | |
102 ;; | |
103 ;; ====================================================================== | |
104 ;; | |
105 ;; don't need rnewspost.el to rewrite the header. This only works | |
106 ;; with diffs to rnewspost.el that I posted with the original | |
107 ;; superyank code. | |
108 ;; | |
109 (setq news-reply-header-hook nil) | |
110 | |
111 ;; ********************************************************************** | |
112 ;; start of user defined variables | |
113 ;; ********************************************************************** | |
114 ;; | |
115 ;; this section defines variables that control the operation of | |
116 ;; super-mail-yank. Most of these are described in the comment section | |
117 ;; as well as the DOCSTRING. | |
118 ;; | |
119 | |
120 ;; | |
121 ;; ---------------------------------------------------------------------- | |
122 ;; | |
123 ;; this variable holds the default author's name for citations | |
124 ;; | |
125 (defvar sy-default-attribution "Anon" | |
126 "String that describes attribution to unknown person. This string | |
127 should not contain the citation string.") | |
128 | |
129 ;; | |
130 ;; ---------------------------------------------------------------------- | |
131 ;; | |
132 ;; string used as an end delimiter for both nested and non-nested citations | |
133 ;; | |
134 (defvar sy-citation-string ">" | |
135 "String to use as an end-delimiter for citations. This string is | |
136 used in both nested and non-nested citations. For best results, use a | |
137 single character with no trailing space. Most commonly used string | |
138 is: \">\.") | |
139 | |
140 ;; | |
141 ;; ---------------------------------------------------------------------- | |
142 ;; | |
143 ;; variable controlling citation type, nested or non-nested | |
144 ;; | |
145 (defvar sy-nested-citation-p nil | |
146 "Non-nil uses nested citations, nil uses non-nested citations. | |
147 Nested citations are of the style: | |
148 | |
149 I wrote this | |
150 > He wrote this | |
151 >> She replied to something he wrote | |
152 | |
153 Non-nested citations are of the style: | |
154 | |
155 I wrote this | |
156 John> He wrote this | |
157 Jane> She originally wrote this") | |
158 | |
159 | |
160 ;; | |
161 ;; ---------------------------------------------------------------------- | |
162 ;; | |
163 ;; regular expression that matches existing citations | |
164 ;; | |
165 (defvar sy-cite-regexp "[a-zA-Z0-9]*>" | |
166 "Regular expression that describes how an already cited line in an | |
167 article begins. The regexp is only used at the beginning of a line, | |
168 so it doesn't need to begin with a '^'.") | |
169 | |
170 ;; | |
171 ;; ---------------------------------------------------------------------- | |
172 ;; | |
173 ;; regular expression that delimits names from titles in the field that | |
174 ;; looks like: (John X. Doe -- Computer Hacker Extraordinaire) | |
175 ;; | |
176 (defvar sy-titlecue-regexp "\\s +-+\\s +" | |
177 | |
178 "Regular expression that delineates names from titles in the name | |
179 field. Often, people will set up their name field to look like this: | |
180 | |
181 (John Xavier Doe -- Computer Hacker Extraordinaire) | |
182 | |
183 Set to nil to treat entire field as a name.") | |
184 | |
185 ;; | |
186 ;; ---------------------------------------------------------------------- | |
187 ;; | |
188 ;; | |
189 (defvar sy-preferred-attribution 2 | |
190 | |
191 "This is an integer indicating what the user's preference is in | |
192 attribution style, based on the following key: | |
193 | |
194 0: email address name is preferred | |
195 1: initials are preferred | |
196 2: first name is preferred | |
197 3: last name is preferred | |
198 | |
199 The value of this variable may also be greater than 3, which would | |
200 allow you to prefer the 2nd through nth - 1 name. If the preferred | |
201 attribution is nil or the empty string, then the secondary preferrence | |
202 will be the first name. After that, the entire name alist is search | |
203 until a non-empty, non-nil name is found. If no such name is found, | |
204 then the user is either queried or the default attribution string is | |
205 used depending on the value of sy-confirm-always-p. | |
206 | |
207 Examples: | |
208 | |
209 assume the from: line looks like this: | |
210 | |
211 from: doe@computer.some.where.com (John Xavier Doe) | |
212 | |
213 The following preferences would return these strings: | |
214 | |
215 0: \"doe\" | |
216 1: \"JXD\" | |
217 2: \"John\" | |
218 3: \"Doe\" | |
219 4: \"Xavier\" | |
220 | |
221 anything else would return \"John\".") | |
222 | |
223 ;; | |
224 ;; ---------------------------------------------------------------------- | |
225 ;; | |
226 (defvar sy-confirm-always-p t | |
227 "If t, always confirm attribution string before inserting into | |
228 buffer.") | |
229 | |
230 | |
231 ;; | |
232 ;; ---------------------------------------------------------------------- | |
233 ;; | |
234 ;; informative header hook | |
235 ;; | |
236 (defvar sy-rewrite-header-hook 'sy-header-on-said | |
237 "Hook for inserting informative header at the top of the yanked | |
238 message. Set to nil for no header. Here is a list of predefined | |
239 header styles; you can use these as a model to write you own: | |
240 | |
241 sy-header-on-said [default]: On 14-Jun-1989 GMT, | |
242 John Xavier Doe said: | |
243 | |
244 sy-header-inarticle-writes: In article <123456789> John Xavier Doe writes: | |
245 | |
246 sy-header-regarding-writes: Regarding RE: superyank; John Xavier Doe adds: | |
247 | |
248 sy-header-verbose: On 14-Jun-1989 GMT, John Xavier Doe | |
249 from the organization Great Company | |
250 has this to say about article <123456789> | |
251 in newsgroups misc.misc | |
252 concerning RE: superyank | |
253 referring to previous articles <987654321> | |
254 | |
255 You can use the following variables as information strings in your header: | |
256 | |
257 sy-reply-yank-date: the date field [ex: 14-Jun-1989 GMT] | |
258 sy-reply-yank-from: the from field [ex: John Xavier Doe] | |
259 sy-reply-yank-message-id: the message id [ex: <123456789>] | |
260 sy-reply-yank-subject: the subject line [ex: RE: superyank] | |
261 sy-reply-yank-newsgroup: the newsgroup name for GNUS [ex: misc.misc] | |
262 sy-reply-yank-references: the article references [ex: <987654321>] | |
263 sy-reply-yank-organization: the author's organization [ex: Great Company] | |
264 | |
265 If a field can't be found, because it doesn't exist or is not being | |
266 shown, perhaps because of toggle-headers, the corresponding field | |
267 variable will contain the string \"mumble mumble\".") | |
268 | |
269 ;; | |
270 ;; ---------------------------------------------------------------------- | |
271 ;; | |
272 ;; non-nil means downcase the author's name string | |
273 ;; | |
274 (defvar sy-downcase-p nil | |
275 "Non-nil means downcase the author's name string.") | |
276 | |
277 ;; | |
278 ;; ---------------------------------------------------------------------- | |
279 ;; | |
280 ;; controls removal of leading white spaces | |
281 ;; | |
282 (defvar sy-left-justify-p nil | |
283 "If non-nil, delete all leading white space before citing.") | |
284 | |
285 ;; | |
286 ;; ---------------------------------------------------------------------- | |
287 ;; | |
288 ;; controls auto filling of region | |
289 ;; | |
290 (defvar sy-auto-fill-region-p nil | |
291 "If non-nil, automatically fill each paragraph that is cited. If | |
292 nil, do not auto fill each paragraph.") | |
293 | |
294 | |
295 ;; | |
296 ;; ---------------------------------------------------------------------- | |
297 ;; | |
298 ;; controls use of preferred attribution only, or use of attribution search | |
299 ;; scheme if the preferred attrib can't be found. | |
300 ;; | |
301 (defvar sy-use-only-preference-p nil | |
302 | |
303 "If non-nil, then only the preferred attribution string will be | |
304 used. If the preferred attribution string can not be found, then the | |
305 sy-default-attribution will be used. If nil, and the preferred | |
306 attribution string is not found, then some secondary scheme will be | |
307 employed to find a suitable attribution string.") | |
308 | |
309 ;; ********************************************************************** | |
310 ;; end of user defined variables | |
311 ;; ********************************************************************** | |
312 | |
313 ;; | |
314 ;; ---------------------------------------------------------------------- | |
315 ;; | |
316 ;; The new citation style means we can clean out other headers in addition | |
317 ;; to those previously cleaned out. Anyway, we create our own headers. | |
318 ;; Also, we want to clean out any headers that gnus puts in. Add to this | |
319 ;; for other mail or news readers you may be using. | |
320 ;; | |
321 (setq mail-yank-ignored-headers "^via:\\|^origin:\\|^status:\\|^re\\(mail\\|ceiv\\)ed\\|^[a-z-]*message-id:\\|^\\(summary-\\)?line[s]?:\\|^cc:\\|^subject:\\|^\\(\\(in-\\)?reply-\\)?to:\\|^\\(\\(return\\|reply\\)-\\)?path:\\|^\\(posted-\\)?date:\\|^\\(mail-\\)?from:\\|^newsgroup[s]?:\\|^organization:\\|^keywords:\\|^distribution:\\|^references:") | |
322 | |
323 ;; | |
324 ;; ---------------------------------------------------------------------- | |
325 ;; | |
326 ;; global variables, not user accessable | |
327 ;; | |
328 (setq sy-persist-attribution (concat sy-default-attribution "> ")) | |
329 (setq sy-reply-yank-date "") | |
330 (setq sy-reply-yank-from "") | |
331 (setq sy-reply-yank-message-id "") | |
332 (setq sy-reply-yank-subject "") | |
333 (setq sy-reply-yank-newsgroups "") | |
334 (setq sy-reply-yank-references "") | |
335 (setq sy-reply-yank-organization "") | |
336 | |
337 ;; | |
338 ;; ====================================================================== | |
339 ;; | |
340 ;; This section contains primitive functions used in the schemes. They | |
341 ;; extract name fields from various parts of the "from:" field based on | |
342 ;; the control variables described above. | |
343 ;; | |
344 ;; Some will use recursion to pick out the correct namefield in the namestring | |
345 ;; or the list of initials. These functions all scan a string that contains | |
346 ;; the name, ie: "John Xavier Doe". There is no limit on the number of names | |
347 ;; in the string. Also note that all white spaces are basically ignored and | |
348 ;; are stripped from the returned strings, and titles are ignored if | |
349 ;; sy-titlecue-regexp is set to non-nil. | |
350 ;; | |
351 ;; Others will use methods to try to extract the name from the email | |
352 ;; address of the originator. The types of addresses readable are | |
353 ;; described above. | |
354 | |
355 ;; | |
356 ;; ---------------------------------------------------------------------- | |
357 ;; | |
358 ;; try to extract the name from an email address of the form | |
359 ;; name%[stuff] | |
360 ;; | |
361 ;; Unlike the get-name functions above, these functions operate on the | |
362 ;; buffer instead of a supplied name-string. | |
363 ;; | |
364 (defun sy-%-style-address () | |
365 (beginning-of-line) | |
366 (buffer-substring | |
367 (progn (re-search-forward "%" (point-max) t) | |
368 (if (not (bolp)) (forward-char -1)) | |
369 (point)) | |
370 (progn (re-search-backward "^\\|[^a-zA-Z0-9]") | |
371 (point)))) | |
372 | |
373 ;; | |
374 ;; ---------------------------------------------------------------------- | |
375 ;; | |
376 ;; try to extract names from addresses with the form: | |
377 ;; [stuff]name@[stuff] | |
378 ;; | |
379 (defun sy-@-style-address () | |
380 (beginning-of-line) | |
381 (buffer-substring | |
382 (progn (re-search-forward "@" (point-max) t) | |
383 (if (not (bolp)) (forward-char -1)) | |
384 (point)) | |
385 (progn (re-search-backward "^\\|[^a-zA-Z0-0]") | |
386 (if (not (bolp)) (forward-char 1)) | |
387 (point)))) | |
388 | |
389 ;; | |
390 ;; ---------------------------------------------------------------------- | |
391 ;; | |
392 ;; try to extract the name from addresses with the form: | |
393 ;; [stuff]![stuff]...!name[stuff] | |
394 ;; | |
395 (defun sy-!-style-address () | |
396 (beginning-of-line) | |
397 (buffer-substring | |
398 (progn (while (re-search-forward "!" (point-max) t)) | |
399 (point)) | |
400 (progn (re-search-forward "[^a-zA-Z0-9]\\|$") | |
401 (if (not (eolp)) (forward-char -1)) | |
402 (point)))) | |
403 | |
404 ;; | |
405 ;; ---------------------------------------------------------------------- | |
406 ;; | |
407 ;; using the different email name schemes, try each one until you get a | |
408 ;; non-nil entry | |
409 ;; | |
410 (defun sy-get-emailname () | |
411 (let ((en1 (sy-%-style-address)) | |
412 (en2 (sy-@-style-address)) | |
413 (en3 (sy-!-style-address))) | |
414 (cond | |
415 ((not (string-equal en1 "")) en1) | |
416 ((not (string-equal en2 "")) en2) | |
417 ((not (string-equal en3 "")) en3) | |
418 (t "")))) | |
419 | |
420 ;; | |
421 ;; ---------------------------------------------------------------------- | |
422 ;; | |
423 ;; returns the "car" of the namestring, really the first namefield | |
424 ;; | |
425 ;; (sy-string-car "John Xavier Doe") | |
426 ;; => "John" | |
427 ;; | |
428 (defun sy-string-car (namestring) | |
429 (substring namestring | |
430 (progn (string-match "\\s *" namestring) (match-end 0)) | |
431 (progn (string-match "\\s *\\S +" namestring) (match-end 0)))) | |
432 | |
433 ;; | |
434 ;; ---------------------------------------------------------------------- | |
435 ;; | |
436 ;; returns the "cdr" of the namestring, really the whole string from | |
437 ;; after the first name field to the end of the string. | |
438 ;; | |
439 ;; (sy-string-cdr "John Xavier Doe") | |
440 ;; => "Xavier Doe" | |
441 ;; | |
442 (defun sy-string-cdr (namestring) | |
443 (substring namestring | |
444 (progn (string-match "\\s *\\S +\\s *" namestring) | |
445 (match-end 0)))) | |
446 | |
447 ;; | |
448 ;; ---------------------------------------------------------------------- | |
449 ;; | |
450 ;; convert a namestring to a list of namefields | |
451 ;; | |
452 ;; (sy-namestring-to-list "John Xavier Doe") | |
453 ;; => ("John" "Xavier" "Doe") | |
454 ;; | |
455 (defun sy-namestring-to-list (namestring) | |
456 (if (not (string-match namestring "")) | |
457 (append (list (sy-string-car namestring)) | |
458 (sy-namestring-to-list (sy-string-cdr namestring))))) | |
459 | |
460 ;; | |
461 ;; ---------------------------------------------------------------------- | |
462 ;; | |
463 ;; strip the initials from each item in the list and return a string | |
464 ;; that is the concatenation of the initials | |
465 ;; | |
466 (defun sy-strip-initials (raw-nlist) | |
467 (if (not raw-nlist) | |
468 nil | |
469 (concat (substring (car raw-nlist) 0 1) | |
470 (sy-strip-initials (cdr raw-nlist))))) | |
471 | |
472 | |
473 ;; | |
474 ;; ---------------------------------------------------------------------- | |
475 ;; | |
476 ;; using the namestring, build a list which is in the following order | |
477 ;; | |
478 ;; (email, initials, firstname, lastname, name1, name2, name3 ... nameN-1) | |
479 ;; | |
480 (defun sy-build-ordered-namelist (namestring) | |
481 (let* ((raw-nlist (sy-namestring-to-list namestring)) | |
482 (initials (sy-strip-initials raw-nlist)) | |
483 (firstname (car raw-nlist)) | |
484 (revnames (reverse (cdr raw-nlist))) | |
485 (lastname (car revnames)) | |
486 (midnames (reverse (cdr revnames))) | |
487 (emailnames (sy-get-emailname))) | |
488 (append (list emailnames) | |
489 (list initials) | |
490 (list firstname) | |
491 (list lastname) | |
492 midnames))) | |
493 | |
494 ;; | |
495 ;; ---------------------------------------------------------------------- | |
496 ;; | |
497 ;; Query the user for the attribution string. Supply sy-default-attribution | |
498 ;; as the default choice. | |
499 ;; | |
500 (defun sy-query-for-attribution () | |
501 (concat | |
502 (let* ((prompt (concat "Enter attribution string: (default " | |
503 sy-default-attribution | |
504 ") ")) | |
505 (query (read-input prompt)) | |
506 (attribution (if (string-equal query "") | |
507 sy-default-attribution | |
508 query))) | |
509 (if sy-downcase-p | |
510 (downcase attribution) | |
511 attribution)) | |
512 sy-citation-string)) | |
513 | |
514 | |
515 ;; | |
516 ;; ---------------------------------------------------------------------- | |
517 ;; | |
518 ;; parse the current line for the namestring | |
519 ;; | |
520 (defun sy-get-namestring () | |
521 (save-restriction | |
522 (beginning-of-line) | |
523 (if (re-search-forward "(.*)" (point-max) t) | |
524 (let ((start (progn | |
525 (beginning-of-line) | |
526 (re-search-forward "\\((\\s *\\)\\|$" (point-max) t) | |
527 (point))) | |
528 (end (progn | |
529 (re-search-forward | |
530 (concat "\\(\\s *\\()\\|" sy-titlecue-regexp "\\)\\)\\|$") | |
531 (point-max) t) | |
532 (point)))) | |
533 (narrow-to-region start end) | |
534 (let ((start (progn | |
535 (beginning-of-line) | |
536 (point))) | |
537 (end (progn | |
538 (end-of-line) | |
539 (re-search-backward | |
540 (concat "\\s *\\()\\|" sy-titlecue-regexp "\\)$") | |
541 (point-min) t) | |
542 (point)))) | |
543 (buffer-substring start end))) | |
544 (let ((start (progn | |
545 (beginning-of-line) | |
546 (re-search-forward "^\"*") | |
547 (point))) | |
548 (end (progn | |
549 (re-search-forward "\\(\\s *[a-zA-Z0-9\\.]+\\)*" | |
550 (point-max) t) | |
551 (point)))) | |
552 (buffer-substring start end))))) | |
553 | |
554 | |
555 ;; | |
556 ;; ---------------------------------------------------------------------- | |
557 ;; | |
558 ;; scan the nlist and return the integer pointing to the first legal | |
559 ;; non-empty namestring. Returns the integer pointing to the index | |
560 ;; in the nlist of the preferred namestring, or nil if no legal | |
561 ;; non-empty namestring could be found. | |
562 ;; | |
563 (defun sy-return-preference-n (nlist) | |
564 (let ((p sy-preferred-attribution) | |
565 (exception nil)) | |
566 ;; | |
567 ;; check to be sure the index is not out-of-bounds | |
568 ;; | |
569 (cond | |
570 ((< p 0) (setq p 2) (setq exception t)) | |
571 ((not (nth p nlist)) (setq p 2) (setq exception t))) | |
572 ;; | |
573 ;; check to be sure that the explicit preference is not empty | |
574 ;; | |
575 (if (string-equal (nth p nlist) "") | |
576 (progn (setq p 0) | |
577 (setq exception t))) | |
578 ;; | |
579 ;; find the first non-empty namestring | |
580 ;; | |
581 (while (and (nth p nlist) | |
582 (string-equal (nth p nlist) "")) | |
583 (setq exception t) | |
584 (setq p (+ p 1))) | |
585 ;; | |
586 ;; return the preference index if non-nil, otherwise nil | |
587 ;; | |
588 (if (or (and exception sy-use-only-preference-p) | |
589 (not (nth p nlist))) | |
590 nil | |
591 p))) | |
592 | |
593 ;; | |
594 ;; | |
595 ;; ---------------------------------------------------------------------- | |
596 ;; | |
597 ;; rebuild the nlist into an alist for completing-read. Use as a guide | |
598 ;; the index of the preferred name field. Get the actual preferred | |
599 ;; name field base on other factors (see above). If no actual preferred | |
600 ;; name field is found, then query the user for the attribution string. | |
601 ;; | |
602 ;; also note that the nlist is guaranteed to be non-empty. At the very | |
603 ;; least it will consist of 4 empty strings ("" "" "" "") | |
604 ;; | |
605 (defun sy-nlist-to-alist (nlist) | |
606 (let ((preference (sy-return-preference-n nlist)) | |
607 alist | |
608 (n 0)) | |
609 ;; | |
610 ;; check to be sure preference is not nil | |
611 ;; | |
612 (if (not preference) | |
613 (setq alist (list (cons (sy-query-for-attribution) nil))) | |
614 ;; | |
615 ;; preference is non-nil | |
616 ;; | |
617 (setq alist (list (cons (nth preference nlist) nil))) | |
618 (while (nth n nlist) | |
619 (if (= n preference) nil | |
620 (setq alist (append alist (list (cons (nth n nlist) nil))))) | |
621 (setq n (+ n 1)))) | |
622 alist)) | |
623 | |
624 | |
625 | |
626 ;; | |
627 ;; ---------------------------------------------------------------------- | |
628 ;; | |
629 ;; confirm if desired after the alist has been built | |
630 ;; | |
631 (defun sy-get-attribution (alist) | |
632 (concat | |
633 ;; | |
634 ;; check to see if nested citations are to be used | |
635 ;; | |
636 (if sy-nested-citation-p | |
637 "" | |
638 ;; | |
639 ;; check to see if confirmation is needed | |
640 ;; if not, just return the preference (first element in alist) | |
641 ;; | |
642 (if (not sy-confirm-always-p) | |
643 (car (car alist)) | |
644 ;; | |
645 ;; confirmation is requested so build the prompt, confirm | |
646 ;; and return the chosen string | |
647 ;; | |
648 (let* (ignore | |
649 (prompt (concat "Complete attribution string: (default " | |
650 (car (car alist)) | |
651 ") ")) | |
652 ;; | |
653 ;; set up the local completion keymap | |
654 ;; | |
655 (minibuffer-local-must-match-map | |
656 (let ((map (make-sparse-keymap))) | |
657 (define-key map "?" 'minibuffer-completion-help) | |
658 (define-key map " " 'minibuffer-complete-word) | |
659 (define-key map "\t" 'minibuffer-complete) | |
660 (define-key map "\00A" 'exit-minibuffer) | |
661 (define-key map "\00D" 'exit-minibuffer) | |
662 (define-key map "\007" | |
663 '(lambda () | |
664 (interactive) | |
665 (beep) | |
666 (exit-minibuffer))) | |
667 map)) | |
668 ;; | |
669 ;; read the completion | |
670 ;; | |
671 (attribution (completing-read prompt alist)) | |
672 ;; | |
673 ;; check attribution string for emptyness | |
674 ;; | |
675 (choice (if (or (not attribution) | |
676 (string-equal attribution "")) | |
677 (car (car alist)) | |
678 attribution))) | |
679 | |
680 (if sy-downcase-p | |
681 (downcase choice) | |
682 choice)))) | |
683 sy-citation-string)) | |
684 | |
685 | |
686 ;; | |
687 ;; ---------------------------------------------------------------------- | |
688 ;; | |
689 ;; this function will scan the current rmail buffer, narrowing it to the | |
690 ;; from: line, then using this, it will try to decipher some names from | |
691 ;; that line. It will then build the name alist and try to confirm | |
692 ;; its choice of attribution strings. It returns the chosen attribution | |
693 ;; string. | |
694 ;; | |
695 (defun sy-scan-rmail-for-names (rmailbuffer) | |
696 (save-excursion | |
697 (let ((case-fold-search t) | |
698 alist | |
699 attribution) | |
700 (switch-to-buffer rmailbuffer) | |
701 (goto-char (point-min)) | |
702 ;; | |
703 ;; be sure there is a from: line | |
704 ;; | |
705 (if (not (re-search-forward "^from:\\s *" (point-max) t)) | |
706 (setq attribution (sy-query-for-attribution)) | |
707 ;; | |
708 ;; if there is a from: line, then scan the narrow the buffer, | |
709 ;; grab the namestring, and build the alist, then using this | |
710 ;; get the attribution string. | |
711 ;; | |
712 (save-restriction | |
713 (narrow-to-region (point) | |
714 (progn (end-of-line) (point))) | |
715 (let* ((namestring (sy-get-namestring)) | |
716 (nlist (sy-build-ordered-namelist namestring))) | |
717 (setq alist (sy-nlist-to-alist nlist)))) | |
718 ;; | |
719 ;; we've built the alist, now confirm the attribution choice | |
720 ;; if appropriate | |
721 ;; | |
722 (setq attribution (sy-get-attribution alist))) | |
723 attribution))) | |
724 | |
725 | |
726 ;; | |
727 ;; ====================================================================== | |
728 ;; | |
729 ;; the following function insert of citations, writing of headers, filling | |
730 ;; paragraphs and general higher level operations | |
731 ;; | |
732 | |
733 ;; | |
734 ;; ---------------------------------------------------------------------- | |
735 ;; | |
736 ;; insert a nested citation | |
737 ;; | |
738 (defun sy-insert-citation (start end cite-string) | |
739 (save-excursion | |
740 (goto-char end) | |
741 (setq end (point-marker)) | |
742 (goto-char start) | |
743 (or (bolp) | |
744 (forward-line 1)) | |
745 | |
746 (let ((fill-prefix (concat cite-string " ")) | |
747 (fstart (point)) | |
748 (fend (point))) | |
749 | |
750 (while (< (point) end) | |
751 ;; | |
752 ;; remove leading tabs if desired | |
753 ;; | |
754 (if sy-left-justify-p | |
755 (delete-region (point) | |
756 (progn (skip-chars-forward " \t") (point)))) | |
757 ;; | |
758 ;; check to see if the current line should be cited | |
759 ;; | |
760 (if (or (eolp) | |
761 (looking-at sy-cite-regexp)) | |
762 ;; | |
763 ;; do not cite this line unless nested-citations are to be | |
764 ;; used | |
765 ;; | |
766 (progn | |
767 (or (eolp) | |
768 (if sy-nested-citation-p | |
769 (insert cite-string))) | |
770 | |
771 ;; set fill start and end points | |
772 ;; | |
773 (or (= fstart fend) | |
774 (not sy-auto-fill-region-p) | |
775 (progn (goto-char fend) | |
776 (or (not (eolp)) | |
777 (setq fend (+ fend 1))) | |
778 (fill-region-as-paragraph fstart fend))) | |
779 (setq fstart (point)) | |
780 (setq fend (point))) | |
781 | |
782 ;; else | |
783 ;; | |
784 (insert fill-prefix) | |
785 (end-of-line) | |
786 (setq fend (point))) | |
787 | |
788 (forward-line 1))) | |
789 (move-marker end nil))) | |
790 | |
791 ;; | |
792 ;; ---------------------------------------------------------------------- | |
793 ;; | |
794 ;; yank a particular field into a holding variable | |
795 ;; | |
796 (defun sy-yank-fields (start) | |
797 (save-excursion | |
798 (goto-char start) | |
799 (setq sy-reply-yank-date (mail-fetch-field "date") | |
800 sy-reply-yank-from (mail-fetch-field "from") | |
801 sy-reply-yank-subject (mail-fetch-field "subject") | |
802 sy-reply-yank-newsgroups (mail-fetch-field "newsgroups") | |
803 sy-reply-yank-references (mail-fetch-field "references") | |
804 sy-reply-yank-message-id (mail-fetch-field "message-id") | |
805 sy-reply-yank-organization (mail-fetch-field "organization")) | |
806 (or sy-reply-yank-date | |
807 (setq sy-reply-yank-date "mumble mumble")) | |
808 (or sy-reply-yank-from | |
809 (setq sy-reply-yank-from "mumble mumble")) | |
810 (or sy-reply-yank-subject | |
811 (setq sy-reply-yank-subject "mumble mumble")) | |
812 (or sy-reply-yank-newsgroups | |
813 (setq sy-reply-yank-newsgroups "mumble mumble")) | |
814 (or sy-reply-yank-references | |
815 (setq sy-reply-yank-references "mumble mumble")) | |
816 (or sy-reply-yank-message-id | |
817 (setq sy-reply-yank-message-id "mumble mumble")) | |
818 (or sy-reply-yank-organization | |
819 (setq sy-reply-yank-organization "mumble mumble")))) | |
820 | |
821 ;; | |
822 ;; ---------------------------------------------------------------------- | |
823 ;; | |
824 ;; rewrite the header to be more conversational | |
825 ;; | |
826 (defun sy-rewrite-headers (start) | |
827 (goto-char start) | |
828 (run-hooks 'sy-rewrite-header-hook)) | |
829 | |
830 ;; | |
831 ;; ---------------------------------------------------------------------- | |
832 ;; | |
833 ;; some different styles of headers | |
834 ;; | |
835 (defun sy-header-on-said () | |
836 (insert-string "\nOn " sy-reply-yank-date ",\n" | |
837 sy-reply-yank-from " said:\n")) | |
838 | |
839 (defun sy-header-inarticle-writes () | |
840 (insert-string "\nIn article " sy-reply-yank-message-id | |
841 " " sy-reply-yank-from " writes:\n")) | |
842 | |
843 (defun sy-header-regarding-writes () | |
844 (insert-string "\nRegarding " sy-reply-yank-subject | |
845 "; " sy-reply-yank-from " adds:\n")) | |
846 | |
847 (defun sy-header-verbose () | |
848 (insert-string "\nOn " sy-reply-yank-date ",\n" | |
849 sy-reply-yank-from "\nfrom the organization " | |
850 sy-reply-yank-organization "\nhad this to say about article " | |
851 sy-reply-yank-message-id "\nin newsgroups " | |
852 sy-reply-yank-newsgroups "\nconcerning " | |
853 sy-reply-yank-subject "\nreferring to previous articles " | |
854 sy-reply-yank-references "\n")) | |
855 | |
856 ;; | |
857 ;; ---------------------------------------------------------------------- | |
858 ;; | |
859 ;; yank the original article in and attribute | |
860 ;; | |
861 (defun sy-yank-original (arg) | |
862 | |
863 "Insert the message being replied to, if any (in rmail/gnus). Puts | |
864 point before the text and mark after. Calls generalized citation | |
865 function sy-insert-citation to cite all allowable lines." | |
866 | |
867 (interactive "P") | |
868 (if mail-reply-buffer | |
869 (let* ((sy-confirm-always-p (if (consp arg) | |
870 t | |
871 sy-confirm-always-p)) | |
872 (attribution (sy-scan-rmail-for-names mail-reply-buffer)) | |
873 (top (point)) | |
874 (start (point)) | |
875 (end (progn (delete-windows-on mail-reply-buffer) | |
876 (insert-buffer mail-reply-buffer) | |
877 (mark)))) | |
878 | |
879 (sy-yank-fields start) | |
880 (sy-rewrite-headers start) | |
881 (setq start (point)) | |
882 (mail-yank-clear-headers top (mark)) | |
883 (setq sy-persist-attribution (concat attribution " ")) | |
884 (sy-insert-citation start end attribution)) | |
885 | |
886 (goto-char top) | |
887 (exchange-point-and-mark))) | |
888 | |
889 | |
890 ;; | |
891 ;; ---------------------------------------------------------------------- | |
892 ;; | |
893 ;; this is here for compatibility with existing mail/news yankers | |
894 ;; overloads the default mail-yank-original | |
895 ;; | |
896 (defun mail-yank-original (arg) | |
897 | |
898 "Yank original message buffer into the reply buffer, citing as per | |
899 user preferences. Numeric Argument forces confirmation. | |
900 | |
901 Here is a description of the superyank.el package, what it does and | |
902 what variables control its operation. This was written by Barry | |
903 Warsaw (warsaw@cme.nist.gov, {...}!uunet!cme-durer!warsaw). | |
904 | |
905 A 'Citation' is the acknowledgement of the original author of a mail | |
906 message. There are two general forms of citation. In 'nested | |
907 citations', indication is made that the cited line was written by | |
908 someone *other* that the current message author (or by that author at | |
909 an earlier time). No indication is made as to the identity of the | |
910 original author. Thus, a nested citation after multiple replies would | |
911 look like this (this is after my reply to a previous message): | |
912 | |
913 >>John originally wrote this | |
914 >>and this as well | |
915 > Jane said that John didn't know | |
916 > what he was talking about | |
917 And that's what I think as well. | |
918 | |
919 In non-nested citations, you won't see multiple \">\" characters at | |
920 the beginning of the line. Non-nested citations will insert an | |
921 informative string at the beginning of a cited line, attributing that | |
922 line to an author. The same message described above might look like | |
923 this if non-nested citations were used: | |
924 | |
925 John> John originally wrote this | |
926 John> and this as well | |
927 Jane> Jane said that John didn't know | |
928 Jane> what he was talking about | |
929 And that's what I think as well. | |
930 | |
931 Notice that my inclusion of Jane's inclusion of John's original | |
932 message did not result in a cited line of the form: Jane>John>. Thus | |
933 no nested citations. The style of citation is controlled by the | |
934 variable `sy-nested-citation-p'. Nil uses non-nested citations and | |
935 non-nil uses old style, nested citations. | |
936 | |
937 The variable `sy-citation-string' is the string to use as a marker for | |
938 a citation, either nested or non-nested. For best results, this | |
939 string should be a single character with no trailing space and is | |
940 typically the character \">\". In non-nested citations this string is | |
941 appended to the attribution string (author's name), along with a | |
942 trailing space. In nested citations, a trailing space is only added | |
943 to a first level citation. | |
944 | |
945 Another important variable is `sy-cite-regexp' which describes strings | |
946 that indicate a previously cited line. This regular expression is | |
947 always used at the beginning of a line so it doesn't need to begin | |
948 with a \"^\" character. Change this variable if you change | |
949 `sy-citation-string'. | |
950 | |
951 The following section only applies to non-nested citations. | |
952 | |
953 This package has a fair amount of intellegence related to deciphering | |
954 the author's name based on information provided by the original | |
955 message buffer. In normal operation, the program will pick out the | |
956 author's first and last names, initials, terminal email address and | |
957 any other names it can find. It will then pick an attribution string | |
958 from this list based on a user defined preference and it will ask for | |
959 confirmation if the user specifies. This package gathers its | |
960 information from the `From:' line of the original message buffer. It | |
961 recognizes From: lines with the following forms: | |
962 | |
963 From: John Xavier Doe <doe@speedy.computer.com> | |
964 From: \"John Xavier Doe\" <doe@speedy.computer.com> | |
965 From: doe@speedy.computer.com (John Xavier Doe) | |
966 From: computer!speedy!doe (John Xavier Doe) | |
967 From: computer!speedy!doe (John Xavier Doe) | |
968 From: doe%speedy@computer.com (John Xavier Doe) | |
969 | |
970 In this case, if confirmation is requested, the following strings will | |
971 be made available for completion and confirmation: | |
972 | |
973 \"John\" | |
974 \"Xavier\" | |
975 \"Doe\" | |
976 \"JXD\" | |
977 \"doe\" | |
978 | |
979 Note that completion is case sensitive. If there was a problem | |
980 picking out a From: line, or any other problem getting even a single | |
981 name, then the user will be queried for an attribution string. The | |
982 default attribution string is set in the variable | |
983 `sy-default-attribution'. | |
984 | |
985 Sometimes people set their name fields so that it also includes a | |
986 title of the form: | |
987 | |
988 From: doe@speedy.computer.com (John Doe -- Hacker Extraordinaire) | |
989 | |
990 To avoid the inclusion of the string \"-- Hacker Extraordinaire\" in | |
991 the name list, the variable `sy-titlecue-regexp' is provided. Its | |
992 default setting will still properly recognize names of the form: | |
993 | |
994 From: xdoe@speedy.computer.com (John Xavier-Doe -- Crazed Hacker) | |
995 | |
996 The variable `sy-preferred-attribution' contains an integer that | |
997 indicates which name field the user prefers to use as the attribution | |
998 string, based on the following key: | |
999 | |
1000 0: email address name is preferred | |
1001 1: initials are preferred | |
1002 2: first name is preferred | |
1003 3: last name is preferred | |
1004 | |
1005 The value can be greater than 3, in which case, you would be | |
1006 preferring the 2nd throught nth -1 name. In any case, if the | |
1007 preferred name can't be found, then one of two actions will be taken | |
1008 depending on the value of the variable `sy-use-only-preference-p'. If | |
1009 this is non-nil, then the `sy-default-attribution will be used. If it | |
1010 is nil, then a secondary scheme will be employed to find a suitable | |
1011 attribution scheme. First, the author's first name will be used. If | |
1012 that can't be found than the name list is searched for the first | |
1013 non-nil, non-empty name string. If still no name can be found, then | |
1014 the user is either queried, or the `sy-default-attribution' is used, | |
1015 depending on the value of `sy-confirm-always-p'. | |
1016 | |
1017 If the variable `sy-confirm-always-p' is non-nil, superyank will always | |
1018 confirm the attribution string with the user before inserting it into | |
1019 the reply buffer. Confirmation is with completion, but the completion | |
1020 list is merely a suggestion; the user can override the list by typing | |
1021 in a string of their choice. | |
1022 | |
1023 The variable `sy-rewrite-header-hook' is a hook that contains a lambda | |
1024 expression which rewrites the informative header at the top of the | |
1025 yanked message. Set to nil to avoid writing any header. | |
1026 | |
1027 You can make superyank autofill each paragraph it cites by setting the | |
1028 variable `sy-auto-fill-region-p' to non-nil. Or set the variable to nil | |
1029 and fill the paragraphs manually with sy-fill-paragraph-manually (see | |
1030 below). | |
1031 | |
1032 Finally, `sy-downcase-p' if non-nil, indicates that you always want to | |
1033 downcase the attribution string before insertion, and | |
1034 `sy-left-justify-p', if non-nil, indicates that you want to delete all | |
1035 leading white space before citing. | |
1036 | |
1037 Since the almost all yanking in other modes (RMAIL, GNUS) is done | |
1038 through the function `mail-yank-original', and since superyank | |
1039 overloads this function, cited yanking is automatically bound to the | |
1040 C-c C-y key. There are three other smaller functions that are | |
1041 provided with superyank and they are bound as below. Try C-h f on | |
1042 each function to get more information on these functions. | |
1043 | |
1044 Key Bindings: | |
1045 | |
1046 C-c C-y mail-yank-original (superyank's version) | |
1047 C-c q sy-fill-paragraph-manually | |
1048 C-c C-q sy-fill-paragraph-manually | |
1049 C-c i sy-insert-persist-attribution | |
1050 C-c C-i sy-insert-persist-attribution | |
1051 C-c C-o sy-open-line | |
1052 | |
1053 | |
1054 Summary of variables, with their default values: | |
1055 | |
1056 sy-default-attribution (default: \"Anon\") | |
1057 Attribution to use if no attribution string can be deciphered | |
1058 from the original message buffer. | |
1059 | |
1060 sy-citation-string (default: \">\") | |
1061 String to append to the attribution string for citation, for | |
1062 best results, it should be one character with no trailing space. | |
1063 | |
1064 sy-nested-citation-p (default: nil) | |
1065 Nil means use non-nested citations, non-nil means use old style | |
1066 nested citations. | |
1067 | |
1068 sy-cite-regexp (default: \"[a-zA-Z0-9]*>\") | |
1069 Regular expression that matches the beginning of a previously | |
1070 cited line. Always used at the beginning of a line so it does | |
1071 not need to start with a \"^\" character. | |
1072 | |
1073 sy-titlecue-regexp (default: \"\\s +-+\\s +\") | |
1074 Regular expression that matches a title delimiter in the name | |
1075 field. | |
1076 | |
1077 sy-preferred-attribution (default: 2) | |
1078 Integer indicating user's preferred attribution field. | |
1079 | |
1080 sy-confirm-always-p (default: t) | |
1081 Non-nil says always confirm with completion before inserting | |
1082 attribution. | |
1083 | |
1084 sy-rewrite-header-hook (default: 'sy-header-on-said) | |
1085 Hook for inserting informative header at the top of the yanked | |
1086 message. | |
1087 | |
1088 sy-downcase-p (default: nil) | |
1089 Non-nil says downcase the attribution string before insertion. | |
1090 | |
1091 sy-left-justify-p (default: nil) | |
1092 Non-nil says delete leading white space before citing. | |
1093 | |
1094 sy-auto-fill-region-p (default: nil) | |
1095 Non-nil says don't auto fill the region. T says auto fill the | |
1096 paragraph. | |
1097 | |
1098 sy-use-only-preference-p (default: nil) | |
1099 If nil, use backup scheme when preferred attribution string | |
1100 can't be found. If non-nil and preferred attribution string | |
1101 can't be found, then use sy-default-attribution." | |
1102 | |
1103 (interactive "P") | |
1104 | |
1105 (local-set-key "\C-cq" 'sy-fill-paragraph-manually) | |
1106 (local-set-key "\C-c\C-q" 'sy-fill-paragraph-manually) | |
1107 (local-set-key "\C-c\i" 'sy-insert-persist-attribution) | |
1108 (local-set-key "\C-c\C-i" 'sy-insert-persist-attribution) | |
1109 (local-set-key "\C-c\C-o" 'sy-open-line) | |
1110 | |
1111 (sy-yank-original arg)) | |
1112 | |
1113 | |
1114 ;; | |
1115 ;; ---------------------------------------------------------------------- | |
1116 ;; | |
1117 ;; based on Bruce Israel's "fill-paragraph-properly", and modified from | |
1118 ;; code posted by David C. Lawrence. Modified to use the persistant | |
1119 ;; attribution if none could be found from the paragraph. | |
1120 ;; | |
1121 (defun sy-fill-paragraph-manually (arg) | |
1122 "Fill paragraph containing or following point, automatically finding | |
1123 the sy-cite-regexp and using it as the prefix. If the sy-cite-regexp | |
1124 is not in the first line of the paragraph, it makes a guess at what | |
1125 the fill-prefix for the paragraph should be by looking at the first | |
1126 line and taking anything up to the first alphanumeric character. | |
1127 | |
1128 Prefix arg means justify both sides of paragraph as well. | |
1129 | |
1130 This function just does fill-paragraph if the fill-prefix is set. If | |
1131 what it deduces to be the paragraph prefix (based on the first line) | |
1132 does not precede each line in the region, then the persistant | |
1133 attribution is used. The persistant attribution is just the last | |
1134 attribution string used to cite lines." | |
1135 | |
1136 (interactive "P") | |
1137 (save-excursion | |
1138 (forward-paragraph) | |
1139 (or (bolp) | |
1140 (newline 1)) | |
1141 | |
1142 (let ((end (point)) | |
1143 st | |
1144 (fill-prefix fill-prefix)) | |
1145 (backward-paragraph) | |
1146 (if (looking-at "\n") | |
1147 (forward-char 1)) | |
1148 (setq st (point)) | |
1149 (if fill-prefix | |
1150 nil | |
1151 (untabify st end) ;; die, scurvy tabs! | |
1152 ;; | |
1153 ;; untabify might have made the paragraph longer character-wise, | |
1154 ;; make sure end reflects the correct location of eop. | |
1155 ;; | |
1156 (forward-paragraph) | |
1157 (setq end (point)) | |
1158 (goto-char st) | |
1159 (if (looking-at sy-cite-regexp) | |
1160 (setq fill-prefix (concat | |
1161 (buffer-substring | |
1162 st (progn (re-search-forward sy-cite-regexp) | |
1163 (point))) | |
1164 " ")) | |
1165 ;; | |
1166 ;; this regexp is is convenient because paragraphs quoted by simple | |
1167 ;; indentation must still yield to us <evil laugh> | |
1168 ;; | |
1169 (while (looking-at "[^a-zA-Z0-9]") | |
1170 (forward-char 1)) | |
1171 (setq fill-prefix (buffer-substring st (point)))) | |
1172 (next-line 1) (beginning-of-line) | |
1173 (while (and (< (point) end) | |
1174 (not (string-equal fill-prefix ""))) | |
1175 ;; | |
1176 ;; if what we decided was the fill-prefix does not precede all | |
1177 ;; of the lines in the paragraph, we probably goofed. In this | |
1178 ;; case set it to the persistant attribution. | |
1179 ;; | |
1180 (if (looking-at (regexp-quote fill-prefix)) | |
1181 () | |
1182 (setq fill-prefix sy-persist-attribution)) | |
1183 (next-line 1) | |
1184 (beginning-of-line))) | |
1185 (fill-region-as-paragraph st end arg)))) | |
1186 | |
1187 ;; | |
1188 ;; ---------------------------------------------------------------------- | |
1189 ;; | |
1190 ;; insert the persistant attribution at point | |
1191 ;; | |
1192 (defun sy-insert-persist-attribution () | |
1193 "Insert the persistant attribution at the beginning of the line that | |
1194 point is on. This string is the last attribution confirmed and used | |
1195 in the yanked reply buffer." | |
1196 (interactive) | |
1197 (save-excursion | |
1198 (beginning-of-line) | |
1199 (insert-string sy-persist-attribution))) | |
1200 | |
1201 | |
1202 ;; | |
1203 ;; ---------------------------------------------------------------------- | |
1204 ;; | |
1205 ;; open a line putting the attribution at the beginning | |
1206 | |
1207 (defun sy-open-line (arg) | |
1208 "Insert a newline and leave point before it. Also inserts the | |
1209 persistant attribution at the beginning of the line. With arg, | |
1210 inserts that many newlines." | |
1211 (interactive "p") | |
1212 (save-excursion | |
1213 (let ((start (point))) | |
1214 (open-line arg) | |
1215 (goto-char start) | |
1216 (forward-line) | |
1217 (while (< 0 arg) | |
1218 (sy-insert-persist-attribution) | |
1219 (forward-line 1) | |
1220 (setq arg (- arg 1)))))) | |
1221 | |
584 | 1222 (provide 'superyank) |
1223 | |
658
7cbd4fcd8b0f
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
1224 ;;; superyank.el ends here |