Mercurial > hg > xemacs-beta
comparison lisp/simple.el @ 1333:1b0339b048ce
[xemacs-hg @ 2003-03-02 09:38:37 by ben]
To: xemacs-patches@xemacs.org
PROBLEMS: Include nt/PROBLEMS and update. Add note about incremental
linking badness.
cmdloop.el, custom.el, dumped-lisp.el, files.el, keydefs.el, keymap.el, lisp-mode.el, make-docfile.el, replace.el, simple.el, subr.el, view-less.el, wid-edit.el: Lots of syncing with FSF 21.2.
Use if-fboundp in wid-edit.el.
New file newcomment.el from FSF.
internals/internals.texi: Fix typo.
(Build-Time Dependencies): New node.
PROBLEMS: Delete.
config.inc.samp, xemacs.mak: Eliminate HAVE_VC6, use SUPPORT_EDIT_AND_CONTINUE in its place.
No incremental linking unless SUPPORT_EDIT_AND_CONTINUE, since it
can cause nasty crashes in pdump. Put warnings about this in
config.inc.samp. Report the full compile flags used for src
and lib-src in the Installation output.
alloc.c, lisp.h, ralloc.c, regex.c: Use ALLOCA() in regex.c to avoid excessive stack allocation.
Also fix subtle problem with REL_ALLOC() -- any call to malloc()
(direct or indirect) may relocate rel-alloced data, causing
buffer text to shift. After any such call, regex must update
all its pointers to such data. Add a system, when
ERROR_CHECK_MALLOC, whereby regex.c indicates all the places
it is prepared to handle malloc()/realloc()/free(), and any
calls anywhere in XEmacs outside of this will trigger an abort.
alloc.c, dialog-msw.c, eval.c, event-stream.c, general-slots.h, insdel.c, lisp.h, menubar-msw.c, menubar-x.c: Change *run_hook*_trapping_problems to take a warning class, not
a string. Factor out code to issue warnings, add flag to
call_trapping_problems() to postpone warning issue, and make
*run_hook*_trapping_problems issue their own warnings tailored
to the hook, postponed in the case of safe_run_hook_trapping_problems()
so that the appropriate message can be issued about resetting to
nil only when not `quit'. Make record_unwind_protect_restoring_int()
non-static.
dumper.c: Issue notes about incremental linking problems under Windows.
fileio.c: Mule-ize encrypt/decrypt-string code.
text.h: Spacing changes.
author | ben |
---|---|
date | Sun, 02 Mar 2003 09:38:54 +0000 |
parents | 465bd3c7d932 |
children | 01c57eb70ae9 |
comparison
equal
deleted
inserted
replaced
1332:6aa23bb3da6b | 1333:1b0339b048ce |
---|---|
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free | 23 ;; along with XEmacs; see the file COPYING. If not, write to the Free |
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
25 ;; 02111-1307, USA. | 25 ;; 02111-1307, USA. |
26 | 26 |
27 ;;; Synched up with: FSF 19.34 [But not very closely]. | 27 ;;; Synched up with: FSF 19.34 [But not very closely]. |
28 ;;; Occasional synching to FSF 21.2, as marked. Comment stuff also | |
29 ;;; synched, and in newcomment.el. | |
28 | 30 |
29 ;;; Commentary: | 31 ;;; Commentary: |
30 | 32 |
31 ;; This file is dumped with XEmacs. | 33 ;; This file is dumped with XEmacs. |
32 | 34 |
2679 (setq end2 (point)) | 2681 (setq end2 (point)) |
2680 (transpose-subr-1) | 2682 (transpose-subr-1) |
2681 (setq arg (1+ arg))))))) | 2683 (setq arg (1+ arg))))))) |
2682 | 2684 |
2683 | 2685 |
2684 (defcustom comment-column 32 | |
2685 "*Column to indent right-margin comments to. | |
2686 Setting this variable automatically makes it local to the current buffer. | |
2687 Each mode establishes a different default value for this variable; you | |
2688 can set the value for a particular mode using that mode's hook." | |
2689 :type 'integer | |
2690 :group 'fill-comments) | |
2691 (make-variable-buffer-local 'comment-column) | |
2692 | |
2693 (defcustom comment-start nil | |
2694 "*String to insert to start a new comment, or nil if no comment syntax." | |
2695 :type '(choice (const :tag "None" nil) | |
2696 string) | |
2697 :group 'fill-comments) | |
2698 | |
2699 (defcustom comment-start-skip nil | |
2700 "*Regexp to match the start of a comment plus everything up to its body. | |
2701 If there are any \\(...\\) pairs, the comment delimiter text is held to begin | |
2702 at the place matched by the close of the first pair." | |
2703 :type '(choice (const :tag "None" nil) | |
2704 regexp) | |
2705 :group 'fill-comments) | |
2706 | |
2707 (defcustom comment-end "" | |
2708 "*String to insert to end a new comment. | |
2709 Should be an empty string if comments are terminated by end-of-line." | |
2710 :type 'string | |
2711 :group 'fill-comments) | |
2712 | |
2713 (defconst comment-indent-hook nil | |
2714 "Obsolete variable for function to compute desired indentation for a comment. | |
2715 Use `comment-indent-function' instead. | |
2716 This function is called with no args with point at the beginning of | |
2717 the comment's starting delimiter.") | |
2718 | |
2719 (defconst comment-indent-function | |
2720 ;; XEmacs - add at least one space after the end of the text on the | |
2721 ;; current line... | |
2722 (lambda () | |
2723 (save-excursion | |
2724 (beginning-of-line) | |
2725 (let ((eol (save-excursion (end-of-line) (point)))) | |
2726 (and comment-start-skip | |
2727 (re-search-forward comment-start-skip eol t) | |
2728 (setq eol (match-beginning 0))) | |
2729 (goto-char eol) | |
2730 (skip-chars-backward " \t") | |
2731 (max comment-column (1+ (current-column)))))) | |
2732 "Function to compute desired indentation for a comment. | |
2733 This function is called with no args with point at the beginning of | |
2734 the comment's starting delimiter.") | |
2735 | |
2736 (defcustom block-comment-start nil | |
2737 "*String to insert to start a new comment on a line by itself. | |
2738 If nil, use `comment-start' instead. | |
2739 Note that the regular expression `comment-start-skip' should skip this string | |
2740 as well as the `comment-start' string." | |
2741 :type '(choice (const :tag "Use `comment-start'" nil) | |
2742 string) | |
2743 :group 'fill-comments) | |
2744 | |
2745 (defcustom block-comment-end nil | |
2746 "*String to insert to end a new comment on a line by itself. | |
2747 Should be an empty string if comments are terminated by end-of-line. | |
2748 If nil, use `comment-end' instead." | |
2749 :type '(choice (const :tag "Use `comment-end'" nil) | |
2750 string) | |
2751 :group 'fill-comments) | |
2752 | |
2753 (defun indent-for-comment () | |
2754 "Indent this line's comment to comment column, or insert an empty | |
2755 comment. Comments starting in column 0 are not moved." | |
2756 (interactive "*") | |
2757 (let* ((empty (save-excursion (beginning-of-line) | |
2758 (looking-at "[ \t]*$"))) | |
2759 (starter (or (and empty block-comment-start) comment-start)) | |
2760 (ender (or (and empty block-comment-end) comment-end))) | |
2761 (if (null starter) | |
2762 (error "No comment syntax defined") | |
2763 (let* ((eolpos (save-excursion (end-of-line) (point))) | |
2764 cpos indent begpos) | |
2765 (beginning-of-line) | |
2766 (if (re-search-forward comment-start-skip eolpos 'move) | |
2767 (progn (setq cpos (point-marker)) | |
2768 ;; Find the start of the comment delimiter. | |
2769 ;; If there were paren-pairs in comment-start-skip, | |
2770 ;; position at the end of the first pair. | |
2771 (if (match-end 1) | |
2772 (goto-char (match-end 1)) | |
2773 ;; If comment-start-skip matched a string with | |
2774 ;; internal whitespace (not final whitespace) then | |
2775 ;; the delimiter start at the end of that | |
2776 ;; whitespace. Otherwise, it starts at the | |
2777 ;; beginning of what was matched. | |
2778 (skip-syntax-backward " " (match-beginning 0)) | |
2779 (skip-syntax-backward "^ " (match-beginning 0))))) | |
2780 (setq begpos (point)) | |
2781 ;; Compute desired indent. | |
2782 ;; XEmacs change: Preserve indentation of comments starting in | |
2783 ;; column 0, as documented. | |
2784 (cond | |
2785 ((= (current-column) 0) | |
2786 (goto-char begpos)) | |
2787 ((= (current-column) | |
2788 (setq indent (funcall comment-indent-function))) | |
2789 (goto-char begpos)) | |
2790 (t | |
2791 ;; If that's different from current, change it. | |
2792 (skip-chars-backward " \t") | |
2793 (delete-region (point) begpos) | |
2794 (indent-to indent))) | |
2795 ;; An existing comment? | |
2796 (if cpos | |
2797 (progn (goto-char cpos) | |
2798 (set-marker cpos nil)) | |
2799 ;; No, insert one. | |
2800 (insert starter) | |
2801 (save-excursion | |
2802 (insert ender))))))) | |
2803 | |
2804 (defun set-comment-column (arg) | |
2805 "Set the comment column based on point. | |
2806 With no arg, set the comment column to the current column. | |
2807 With just minus as arg, kill any comment on this line. | |
2808 With any other arg, set comment column to indentation of the previous comment | |
2809 and then align or create a comment on this line at that column." | |
2810 (interactive "P") | |
2811 (if (eq arg '-) | |
2812 (kill-comment nil) | |
2813 (if arg | |
2814 (progn | |
2815 (save-excursion | |
2816 (beginning-of-line) | |
2817 (re-search-backward comment-start-skip) | |
2818 (beginning-of-line) | |
2819 (re-search-forward comment-start-skip) | |
2820 (goto-char (match-beginning 0)) | |
2821 (setq comment-column (current-column)) | |
2822 (lmessage 'command "Comment column set to %d" comment-column)) | |
2823 (indent-for-comment)) | |
2824 (setq comment-column (current-column)) | |
2825 (lmessage 'command "Comment column set to %d" comment-column)))) | |
2826 | |
2827 (defun kill-comment (arg) | |
2828 "Kill the comment on this line, if any. | |
2829 With argument, kill comments on that many lines starting with this one." | |
2830 ;; this function loses in a lot of situations. it incorrectly recognizes | |
2831 ;; comment delimiters sometimes (ergo, inside a string), doesn't work | |
2832 ;; with multi-line comments, can kill extra whitespace if comment wasn't | |
2833 ;; through end-of-line, et cetera. | |
2834 (interactive "*P") | |
2835 (or comment-start-skip (error "No comment syntax defined")) | |
2836 (let ((count (prefix-numeric-value arg)) endc) | |
2837 (while (> count 0) | |
2838 (save-excursion | |
2839 (end-of-line) | |
2840 (setq endc (point)) | |
2841 (beginning-of-line) | |
2842 (and (string< "" comment-end) | |
2843 (setq endc | |
2844 (progn | |
2845 (re-search-forward (regexp-quote comment-end) endc 'move) | |
2846 (skip-chars-forward " \t") | |
2847 (point)))) | |
2848 (beginning-of-line) | |
2849 (if (re-search-forward comment-start-skip endc t) | |
2850 (progn | |
2851 (goto-char (match-beginning 0)) | |
2852 (skip-chars-backward " \t") | |
2853 (kill-region (point) endc) | |
2854 ;; to catch comments a line beginnings | |
2855 (indent-according-to-mode)))) | |
2856 (if arg (forward-line 1)) | |
2857 (setq count (1- count))))) | |
2858 | |
2859 ;; This variable: Synched up with 20.7. | |
2860 (defvar comment-padding 1 | |
2861 "Number of spaces `comment-region' puts between comment chars and text. | |
2862 | |
2863 Extra spacing between the comment characters and the comment text | |
2864 makes the comment easier to read. Default is 1. Nil means 0 and is | |
2865 more efficient.") | |
2866 | |
2867 ;; This function: Synched up with 20.7. | |
2868 (defun comment-region (start end &optional arg) | |
2869 "Comment or uncomment each line in the region. | |
2870 With just C-u prefix arg, uncomment each line in region. | |
2871 Numeric prefix arg ARG means use ARG comment characters. | |
2872 If ARG is negative, delete that many comment characters instead. | |
2873 Comments are terminated on each line, even for syntax in which newline does | |
2874 not end the comment. Blank lines do not get comments." | |
2875 ;; if someone wants it to only put a comment-start at the beginning and | |
2876 ;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x | |
2877 ;; is easy enough. No option is made here for other than commenting | |
2878 ;; every line. | |
2879 (interactive "r\nP") | |
2880 (or comment-start (error "No comment syntax is defined")) | |
2881 (if (> start end) (let (mid) (setq mid start start end end mid))) | |
2882 (save-excursion | |
2883 (save-restriction | |
2884 (let ((cs comment-start) (ce comment-end) | |
2885 (cp (when comment-padding | |
2886 (make-string comment-padding ? ))) | |
2887 numarg) | |
2888 (if (consp arg) (setq numarg t) | |
2889 (setq numarg (prefix-numeric-value arg)) | |
2890 ;; For positive arg > 1, replicate the comment delims now, | |
2891 ;; then insert the replicated strings just once. | |
2892 (while (> numarg 1) | |
2893 (setq cs (concat cs comment-start) | |
2894 ce (concat ce comment-end)) | |
2895 (setq numarg (1- numarg)))) | |
2896 ;; Loop over all lines from START to END. | |
2897 (narrow-to-region start end) | |
2898 (goto-char start) | |
2899 ;; if user didn't specify how many comments to remove, be smart | |
2900 ;; and remove the minimal number that all lines have. that way, | |
2901 ;; comments in a region of Elisp code that gets commented out will | |
2902 ;; get put back correctly. | |
2903 (if (eq numarg t) | |
2904 (let ((min-comments 999999)) | |
2905 (while (not (eobp)) | |
2906 (let ((this-comments 0)) | |
2907 (while (looking-at (regexp-quote cs)) | |
2908 (incf this-comments) | |
2909 (forward-char (length cs))) | |
2910 (if (and (> this-comments 0) (< this-comments min-comments)) | |
2911 (setq min-comments this-comments)) | |
2912 (forward-line 1))) | |
2913 (if (< min-comments 999999) | |
2914 (setq numarg (- min-comments))) | |
2915 (goto-char start))) | |
2916 (if (or (eq numarg t) (< numarg 0)) | |
2917 (while (not (eobp)) | |
2918 (let (found-comment) | |
2919 ;; Delete comment start from beginning of line. | |
2920 (if (eq numarg t) | |
2921 (while (looking-at (regexp-quote cs)) | |
2922 (setq found-comment t) | |
2923 (delete-char (length cs))) | |
2924 (let ((count numarg)) | |
2925 (while (and (> 1 (setq count (1+ count))) | |
2926 (looking-at (regexp-quote cs))) | |
2927 (setq found-comment t) | |
2928 (delete-char (length cs))))) | |
2929 ;; Delete comment padding from beginning of line | |
2930 (when (and found-comment comment-padding | |
2931 (looking-at (regexp-quote cp))) | |
2932 (delete-char comment-padding)) | |
2933 ;; Delete comment end from end of line. | |
2934 (if (string= "" ce) | |
2935 nil | |
2936 (if (eq numarg t) | |
2937 (progn | |
2938 (end-of-line) | |
2939 ;; This is questionable if comment-end ends in | |
2940 ;; whitespace. That is pretty brain-damaged, | |
2941 ;; though. | |
2942 (while (progn (skip-chars-backward " \t") | |
2943 (and (>= (- (point) (point-min)) | |
2944 (length ce)) | |
2945 (save-excursion | |
2946 (backward-char (length ce)) | |
2947 (looking-at (regexp-quote ce))))) | |
2948 (delete-char (- (length ce))))) | |
2949 (let ((count numarg)) | |
2950 (while (> 1 (setq count (1+ count))) | |
2951 (end-of-line) | |
2952 ;; This is questionable if comment-end ends in | |
2953 ;; whitespace. That is pretty brain-damaged though | |
2954 (skip-chars-backward " \t") | |
2955 (if (>= (- (point) (point-min)) (length ce)) | |
2956 (save-excursion | |
2957 (backward-char (length ce)) | |
2958 (if (looking-at (regexp-quote ce)) | |
2959 (delete-char (length ce))))))))) | |
2960 (forward-line 1))) | |
2961 | |
2962 (when comment-padding | |
2963 (setq cs (concat cs cp))) | |
2964 (while (not (eobp)) | |
2965 ;; Insert at beginning and at end. | |
2966 (if (looking-at "[ \t]*$") () | |
2967 (insert cs) | |
2968 (if (string= "" ce) () | |
2969 (end-of-line) | |
2970 (insert ce))) | |
2971 (search-forward "\n" nil 'move))))))) | |
2972 | |
2973 ;; XEmacs | 2686 ;; XEmacs |
2974 (defun prefix-region (prefix) | 2687 (defun prefix-region (prefix) |
2975 "Add a prefix string to each line between mark and point." | 2688 "Add a prefix string to each line between mark and point." |
2976 (interactive "sPrefix string: ") | 2689 (interactive "sPrefix string: ") |
2977 (if prefix | 2690 (if prefix |
3332 ;; Disallow missing argument; it's probably a typo for C-x C-f. | 3045 ;; Disallow missing argument; it's probably a typo for C-x C-f. |
3333 (t | 3046 (t |
3334 (error "set-fill-column requires an explicit argument"))) | 3047 (error "set-fill-column requires an explicit argument"))) |
3335 (lmessage 'command "fill-column set to %d" fill-column)) | 3048 (lmessage 'command "fill-column set to %d" fill-column)) |
3336 | 3049 |
3337 (defcustom comment-multi-line t ; XEmacs - this works well with adaptive fill | 3050 |
3338 "*Non-nil means \\[indent-new-comment-line] should continue same comment | 3051 ;; BEGIN SYNCHED WITH FSF 21.2. |
3339 on new line, with no new terminator or starter. | 3052 |
3340 This is obsolete because you might as well use \\[newline-and-indent]." | |
3341 :type 'boolean | |
3342 :group 'fill-comments) | |
3343 | |
3344 (defun indent-new-comment-line (&optional soft) | |
3345 "Break line at point and indent, continuing comment if within one. | |
3346 This indents the body of the continued comment | |
3347 under the previous comment line. | |
3348 | |
3349 This command is intended for styles where you write a comment per line, | |
3350 starting a new comment (and terminating it if necessary) on each line. | |
3351 If you want to continue one comment across several lines, use \\[newline-and-indent]. | |
3352 | |
3353 If a fill column is specified, it overrides the use of the comment column | |
3354 or comment indentation. | |
3355 | |
3356 The inserted newline is marked hard if `use-hard-newlines' is true, | |
3357 unless optional argument SOFT is non-nil." | |
3358 (interactive) | |
3359 (let (comcol comstart) | |
3360 (skip-chars-backward " \t") | |
3361 (if (featurep 'mule) | |
3362 (declare-fboundp (kinsoku-process))) | |
3363 (delete-region (point) | |
3364 (progn (skip-chars-forward " \t") | |
3365 (point))) | |
3366 (if soft (insert ?\n) (newline 1)) | |
3367 (if fill-prefix | |
3368 (progn | |
3369 (indent-to-left-margin) | |
3370 (insert fill-prefix)) | |
3371 ;; #### - Eric Eide reverts to v18 semantics for this function in | |
3372 ;; fa-extras, which I'm not gonna do. His changes are to (1) execute | |
3373 ;; the save-excursion below unconditionally, and (2) uncomment the check | |
3374 ;; for (not comment-multi-line) further below. --Stig | |
3375 ;;#### jhod: probably need to fix this for kinsoku processing | |
3376 (if (not comment-multi-line) | |
3377 (save-excursion | |
3378 (if (and comment-start-skip | |
3379 (let ((opoint (point))) | |
3380 (forward-line -1) | |
3381 (re-search-forward comment-start-skip opoint t))) | |
3382 ;; The old line is a comment. | |
3383 ;; Set WIN to the pos of the comment-start. | |
3384 ;; But if the comment is empty, look at preceding lines | |
3385 ;; to find one that has a nonempty comment. | |
3386 | |
3387 ;; If comment-start-skip contains a \(...\) pair, | |
3388 ;; the real comment delimiter starts at the end of that pair. | |
3389 (let ((win (or (match-end 1) (match-beginning 0)))) | |
3390 (while (and (eolp) (not (bobp)) | |
3391 (let (opoint) | |
3392 (beginning-of-line) | |
3393 (setq opoint (point)) | |
3394 (forward-line -1) | |
3395 (re-search-forward comment-start-skip opoint t))) | |
3396 (setq win (or (match-end 1) (match-beginning 0)))) | |
3397 ;; Indent this line like what we found. | |
3398 (goto-char win) | |
3399 (setq comcol (current-column)) | |
3400 (setq comstart | |
3401 (buffer-substring (point) (match-end 0))))))) | |
3402 (if (and comcol (not fill-prefix)) ; XEmacs - (ENE) from fa-extras. | |
3403 (let ((comment-column comcol) | |
3404 (comment-start comstart) | |
3405 (block-comment-start comstart) | |
3406 (comment-end comment-end)) | |
3407 (and comment-end (not (equal comment-end "")) | |
3408 ; (if (not comment-multi-line) | |
3409 (progn | |
3410 (backward-char 1) | |
3411 (insert comment-end) | |
3412 (forward-char 1)) | |
3413 ; (setq comment-column (+ comment-column (length comment-start)) | |
3414 ; comment-start "") | |
3415 ; ) | |
3416 ) | |
3417 (if (not (eolp)) | |
3418 (setq comment-end "")) | |
3419 (insert ?\n) | |
3420 (backward-char 1) | |
3421 (indent-for-comment) | |
3422 (save-excursion | |
3423 ;; Make sure we delete the newline inserted above. | |
3424 (end-of-line) | |
3425 (delete-char 1))) | |
3426 (indent-according-to-mode))))) | |
3427 | |
3428 | |
3429 (defun set-selective-display (arg) | 3053 (defun set-selective-display (arg) |
3430 "Set `selective-display' to ARG; clear it if no arg. | 3054 "Set `selective-display' to ARG; clear it if no arg. |
3431 When the value of `selective-display' is a number > 0, | 3055 When the value of `selective-display' is a number > 0, |
3432 lines whose indentation is >= that value are not displayed. | 3056 lines whose indentation is >= that value are not displayed. |
3433 The variable `selective-display' has a separate value for each buffer." | 3057 The variable `selective-display' has a separate value for each buffer." |
3469 )))) | 3093 )))) |
3470 (setq selective-display nil)) | 3094 (setq selective-display nil)) |
3471 | 3095 |
3472 (add-hook 'change-major-mode-hook 'nuke-selective-display) | 3096 (add-hook 'change-major-mode-hook 'nuke-selective-display) |
3473 | 3097 |
3474 (defconst overwrite-mode-textual " Ovwrt" | 3098 (defvar overwrite-mode-textual " Ovwrt" |
3475 "The string displayed in the mode line when in overwrite mode.") | 3099 "The string displayed in the mode line when in overwrite mode.") |
3476 (defconst overwrite-mode-binary " Bin Ovwrt" | 3100 (defvar overwrite-mode-binary " Bin Ovwrt" |
3477 "The string displayed in the mode line when in binary overwrite mode.") | 3101 "The string displayed in the mode line when in binary overwrite mode.") |
3478 | 3102 |
3479 (defun overwrite-mode (arg) | 3103 (defun overwrite-mode (arg) |
3480 "Toggle overwrite mode. | 3104 "Toggle overwrite mode. |
3481 With arg, enable overwrite mode if arg is positive, else disable. | 3105 With arg, turn overwrite mode on iff arg is positive. |
3482 In overwrite mode, printing characters typed in replace existing text | 3106 In overwrite mode, printing characters typed in replace existing text |
3483 on a one-for-one basis, rather than pushing it to the right. At the | 3107 on a one-for-one basis, rather than pushing it to the right. At the |
3484 end of a line, such characters extend the line. Before a tab, | 3108 end of a line, such characters extend the line. Before a tab, |
3485 such characters insert until the tab is filled in. | 3109 such characters insert until the tab is filled in. |
3486 \\[quoted-insert] still inserts characters in overwrite mode; this | 3110 \\[quoted-insert] still inserts characters in overwrite mode; this |
3492 'overwrite-mode-textual)) | 3116 'overwrite-mode-textual)) |
3493 (redraw-modeline)) | 3117 (redraw-modeline)) |
3494 | 3118 |
3495 (defun binary-overwrite-mode (arg) | 3119 (defun binary-overwrite-mode (arg) |
3496 "Toggle binary overwrite mode. | 3120 "Toggle binary overwrite mode. |
3497 With arg, enable binary overwrite mode if arg is positive, else disable. | 3121 With arg, turn binary overwrite mode on iff arg is positive. |
3498 In binary overwrite mode, printing characters typed in replace | 3122 In binary overwrite mode, printing characters typed in replace |
3499 existing text. Newlines are not treated specially, so typing at the | 3123 existing text. Newlines are not treated specially, so typing at the |
3500 end of a line joins the line to the next, with the typed character | 3124 end of a line joins the line to the next, with the typed character |
3501 between them. Typing before a tab character simply replaces the tab | 3125 between them. Typing before a tab character simply replaces the tab |
3502 with the character typed. | 3126 with the character typed. |
3511 (if (if (null arg) | 3135 (if (if (null arg) |
3512 (not (eq overwrite-mode 'overwrite-mode-binary)) | 3136 (not (eq overwrite-mode 'overwrite-mode-binary)) |
3513 (> (prefix-numeric-value arg) 0)) | 3137 (> (prefix-numeric-value arg) 0)) |
3514 'overwrite-mode-binary)) | 3138 'overwrite-mode-binary)) |
3515 (redraw-modeline)) | 3139 (redraw-modeline)) |
3140 | |
3141 ;; END SYNCHED WITH FSF 21.2. | |
3142 | |
3516 | 3143 |
3517 (defcustom line-number-mode t | 3144 (defcustom line-number-mode t |
3518 "*Non-nil means display line number in modeline." | 3145 "*Non-nil means display line number in modeline." |
3519 :type 'boolean | 3146 :type 'boolean |
3520 :group 'editing-basics) | 3147 :group 'editing-basics) |
3670 | 3297 |
3671 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3298 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3672 ;; mail composition code ;; | 3299 ;; mail composition code ;; |
3673 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3300 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3674 | 3301 |
3302 ;; BEGIN SYNCHED WITH FSF 21.2. | |
3303 | |
3675 (defcustom mail-user-agent 'sendmail-user-agent | 3304 (defcustom mail-user-agent 'sendmail-user-agent |
3676 "*Your preference for a mail composition package. | 3305 "*Your preference for a mail composition package. |
3677 Various Emacs Lisp packages (e.g. reporter) require you to compose an | 3306 Various Emacs Lisp packages (e.g. Reporter) require you to compose an |
3678 outgoing email message. This variable lets you specify which | 3307 outgoing email message. This variable lets you specify which |
3679 mail-sending package you prefer. | 3308 mail-sending package you prefer. |
3680 | 3309 |
3681 Valid values include: | 3310 Valid values include: |
3682 | 3311 |
3683 sendmail-user-agent -- use the default Emacs Mail package | 3312 `sendmail-user-agent' -- use the default Emacs Mail package. |
3684 mh-e-user-agent -- use the Emacs interface to the MH mail system | 3313 See Info node `(emacs)Sending Mail'. |
3685 message-user-agent -- use the GNUS mail sending package | 3314 `mh-e-user-agent' -- use the Emacs interface to the MH mail system. |
3315 See Info node `(mh-e)'. | |
3316 `message-user-agent' -- use the Gnus Message package. | |
3317 See Info node `(message)'. | |
3318 `gnus-user-agent' -- like `message-user-agent', but with Gnus | |
3319 paraphernalia, particularly the Gcc: header for | |
3320 archiving. | |
3686 | 3321 |
3687 Additional valid symbols may be available; check with the author of | 3322 Additional valid symbols may be available; check with the author of |
3688 your package for details." | 3323 your package for details. The function should return non-nil if it |
3324 succeeds. | |
3325 | |
3326 See also `read-mail-command' concerning reading mail." | |
3689 :type '(radio (function-item :tag "Default Emacs mail" | 3327 :type '(radio (function-item :tag "Default Emacs mail" |
3690 :format "%t\n" | 3328 :format "%t\n" |
3691 sendmail-user-agent) | 3329 sendmail-user-agent) |
3692 (function-item :tag "Gnus mail sending package" | 3330 (function-item :tag "Emacs interface to MH" |
3331 :format "%t\n" | |
3332 mh-e-user-agent) | |
3333 (function-item :tag "Gnus Message package" | |
3693 :format "%t\n" | 3334 :format "%t\n" |
3694 message-user-agent) | 3335 message-user-agent) |
3336 (function-item :tag "Gnus Message with full Gnus features" | |
3337 :format "%t\n" | |
3338 gnus-user-agent) | |
3695 (function :tag "Other")) | 3339 (function :tag "Other")) |
3696 :group 'mail) | 3340 :group 'mail) |
3697 | 3341 |
3698 (defun define-mail-user-agent (symbol composefunc sendfunc | 3342 (defun define-mail-user-agent (symbol composefunc sendfunc |
3699 &optional abortfunc hookvar) | 3343 &optional abortfunc hookvar) |
3734 'sendmail-user-agent-compose 'mail-send-and-exit) | 3378 'sendmail-user-agent-compose 'mail-send-and-exit) |
3735 | 3379 |
3736 (define-mail-user-agent 'message-user-agent | 3380 (define-mail-user-agent 'message-user-agent |
3737 'message-mail 'message-send-and-exit | 3381 'message-mail 'message-send-and-exit |
3738 'message-kill-buffer 'message-send-hook) | 3382 'message-kill-buffer 'message-send-hook) |
3383 | |
3384 (defun rfc822-goto-eoh () | |
3385 ;; Go to header delimiter line in a mail message, following RFC822 rules | |
3386 (goto-char (point-min)) | |
3387 (while (looking-at "^[^: \n]+:\\|^[ \t]") | |
3388 (forward-line 1)) | |
3389 (point)) | |
3739 | 3390 |
3740 (defun sendmail-user-agent-compose (&optional to subject other-headers continue | 3391 (defun sendmail-user-agent-compose (&optional to subject other-headers continue |
3741 switch-function yank-action | 3392 switch-function yank-action |
3742 send-actions) | 3393 send-actions) |
3743 (if switch-function | 3394 (if switch-function |
3745 (special-display-regexps nil) | 3396 (special-display-regexps nil) |
3746 (same-window-buffer-names nil) | 3397 (same-window-buffer-names nil) |
3747 (same-window-regexps nil)) | 3398 (same-window-regexps nil)) |
3748 (funcall switch-function "*mail*"))) | 3399 (funcall switch-function "*mail*"))) |
3749 (let ((cc (cdr (assoc-ignore-case "cc" other-headers))) | 3400 (let ((cc (cdr (assoc-ignore-case "cc" other-headers))) |
3750 (in-reply-to (cdr (assoc-ignore-case "in-reply-to" other-headers)))) | 3401 (in-reply-to (cdr (assoc-ignore-case "in-reply-to" other-headers))) |
3402 (body (cdr (assoc-ignore-case "body" other-headers)))) | |
3751 (or (declare-fboundp | 3403 (or (declare-fboundp |
3752 (mail continue to subject in-reply-to cc yank-action send-actions)) | 3404 (mail continue to subject in-reply-to cc yank-action send-actions)) |
3753 continue | 3405 continue |
3754 (error "Message aborted")) | 3406 (error "Message aborted")) |
3755 (save-excursion | 3407 (save-excursion |
3756 (goto-char (point-min)) | 3408 (rfc822-goto-eoh) |
3757 (search-forward (declare-boundp mail-header-separator)) | |
3758 (beginning-of-line) | |
3759 (while other-headers | 3409 (while other-headers |
3760 (if (not (member (car (car other-headers)) '("in-reply-to" "cc"))) | 3410 (unless (member* (car (car other-headers)) |
3411 '("in-reply-to" "cc" "body") | |
3412 :test 'equalp) | |
3761 (insert (car (car other-headers)) ": " | 3413 (insert (car (car other-headers)) ": " |
3762 (cdr (car other-headers)) "\n")) | 3414 (cdr (car other-headers)) "\n")) |
3763 (setq other-headers (cdr other-headers))) | 3415 (setq other-headers (cdr other-headers))) |
3416 (when body | |
3417 (forward-line 1) | |
3418 (insert body)) | |
3764 t))) | 3419 t))) |
3765 | 3420 |
3766 (define-mail-user-agent 'mh-e-user-agent | 3421 (define-mail-user-agent 'mh-e-user-agent |
3767 'mh-user-agent-compose 'mh-send-letter 'mh-fully-kill-draft | 3422 'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft |
3768 'mh-before-send-letter-hook) | 3423 'mh-before-send-letter-hook) |
3769 | 3424 |
3770 (defun compose-mail (&optional to subject other-headers continue | 3425 (defun compose-mail (&optional to subject other-headers continue |
3771 switch-function yank-action send-actions) | 3426 switch-function yank-action send-actions) |
3772 "Start composing a mail message to send. | 3427 "Start composing a mail message to send. |
3820 | 3475 |
3821 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3822 ;; set variable ;; | 3477 ;; set variable ;; |
3823 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3478 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3824 | 3479 |
3480 (defvar set-variable-value-history nil | |
3481 "History of values entered with `set-variable'.") | |
3482 | |
3825 (defun set-variable (var val) | 3483 (defun set-variable (var val) |
3826 "Set VARIABLE to VALUE. VALUE is a Lisp object. | 3484 "Set VARIABLE to VALUE. VALUE is a Lisp object. |
3827 When using this interactively, supply a Lisp expression for VALUE. | 3485 When using this interactively, enter a Lisp object for VALUE. |
3828 If you want VALUE to be a string, you must surround it with doublequotes. | 3486 If you want VALUE to be a string, you must surround it with doublequotes. |
3487 VALUE is used literally, not evaluated. | |
3488 | |
3829 If VARIABLE is a specifier, VALUE is added to it as an instantiator in | 3489 If VARIABLE is a specifier, VALUE is added to it as an instantiator in |
3830 the 'global locale with nil tag set (see `set-specifier'). | 3490 the 'global locale with nil tag set (see `set-specifier'). |
3831 | 3491 |
3832 If VARIABLE has a `variable-interactive' property, that is used as if | 3492 If VARIABLE has a `variable-interactive' property, that is used as if |
3833 it were the arg to `interactive' (which see) to interactively read the value." | 3493 it were the arg to `interactive' (which see) to interactively read VALUE. |
3494 | |
3495 If VARIABLE has been defined with `defcustom', then the type information | |
3496 in the definition is used to check that VALUE is valid." | |
3834 (interactive | 3497 (interactive |
3835 (let* ((var (read-variable "Set variable: ")) | 3498 (let* ((default-var (variable-at-point)) |
3836 ;; #### - yucky code replication here. This should use something | 3499 (var (if (symbolp default-var) |
3837 ;; from help.el or hyper-apropos.el | 3500 (read-variable (format "Set variable (default %s): " default-var) |
3838 (myhelp | 3501 default-var) |
3839 #'(lambda () | 3502 (read-variable "Set variable: "))) |
3840 (with-output-to-temp-buffer "*Help*" | 3503 (minibuffer-help-form '(describe-variable var)) |
3841 (prin1 var) | 3504 (prop (get var 'variable-interactive)) |
3842 (princ "\nDocumentation:\n") | 3505 (prompt (format "Set %s to value: " var)) |
3843 (princ (substring (documentation-property var 'variable-documentation) | 3506 (val (if prop |
3844 1)) | 3507 ;; Use VAR's `variable-interactive' property |
3845 (if (boundp var) | 3508 ;; as an interactive spec for prompting. |
3846 (let ((print-length 20)) | 3509 (call-interactively `(lambda (arg) |
3847 (princ "\n\nCurrent value: ") | 3510 (interactive ,prop) |
3848 (prin1 (symbol-value var)))) | 3511 arg)) |
3849 (save-excursion | 3512 (read |
3850 (set-buffer standard-output) | 3513 (read-string prompt nil |
3851 (help-mode)) | 3514 'set-variable-value-history))))) |
3852 nil))) | 3515 (list var val))) |
3853 (minibuffer-help-form | 3516 |
3854 '(funcall myhelp))) | 3517 (let ((type (get var 'custom-type))) |
3855 (list var | 3518 (when type |
3856 (let ((prop (get var 'variable-interactive))) | 3519 ;; Match with custom type. |
3857 (if prop | 3520 (require 'cus-edit) |
3858 ;; Use VAR's `variable-interactive' property | 3521 (setq type (widget-convert type)) |
3859 ;; as an interactive spec for prompting. | 3522 (unless (widget-apply type :match val) |
3860 (call-interactively (list 'lambda '(arg) | 3523 (error "Value `%S' does not match type %S of %S" |
3861 (list 'interactive prop) | 3524 val (car type) var)))) |
3862 'arg)) | |
3863 (eval-minibuffer (format "Set %s to value: " var))))))) | |
3864 (if (and (boundp var) (specifierp (symbol-value var))) | 3525 (if (and (boundp var) (specifierp (symbol-value var))) |
3865 (set-specifier (symbol-value var) val) | 3526 (set-specifier (symbol-value var) val) |
3866 (set var val))) | 3527 (set var val)) |
3528 | |
3529 ;; Force a thorough redisplay for the case that the variable | |
3530 ;; has an effect on the display, like `tab-width' has. | |
3531 (force-mode-line-update)) | |
3532 | |
3533 | |
3534 | |
3535 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
3536 ;; forking a twin copy of a buffer ;; | |
3537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
3538 | |
3539 (defvar clone-buffer-hook nil | |
3540 "Normal hook to run in the new buffer at the end of `clone-buffer'.") | |
3541 | |
3542 (defun clone-process (process &optional newname) | |
3543 "Create a twin copy of PROCESS. | |
3544 If NEWNAME is nil, it defaults to PROCESS' name; | |
3545 NEWNAME is modified by adding or incrementing <N> at the end as necessary. | |
3546 If PROCESS is associated with a buffer, the new process will be associated | |
3547 with the current buffer instead. | |
3548 Returns nil if PROCESS has already terminated." | |
3549 (setq newname (or newname (process-name process))) | |
3550 (if (string-match "<[0-9]+>\\'" newname) | |
3551 (setq newname (substring newname 0 (match-beginning 0)))) | |
3552 (when (memq (process-status process) '(run stop open)) | |
3553 (let* ((process-connection-type (process-tty-name process)) | |
3554 (old-kwoq (process-kill-without-query process nil)) | |
3555 (new-process | |
3556 (if (memq (process-status process) '(open)) | |
3557 (apply 'open-network-stream newname | |
3558 (if (process-buffer process) (current-buffer)) | |
3559 ;; FSF: (process-contact process) | |
3560 (process-command process)) | |
3561 (apply 'start-process newname | |
3562 (if (process-buffer process) (current-buffer)) | |
3563 (process-command process))))) | |
3564 (process-kill-without-query new-process old-kwoq) | |
3565 (process-kill-without-query process old-kwoq) | |
3566 ;; FSF 21.2: | |
3567 ; (set-process-inherit-coding-system-flag | |
3568 ; new-process (process-inherit-coding-system-flag process)) | |
3569 (set-process-filter new-process (process-filter process)) | |
3570 (set-process-sentinel new-process (process-sentinel process)) | |
3571 new-process))) | |
3572 | |
3573 ;; things to maybe add (currently partly covered by `funcall mode': | |
3574 ;; - syntax-table | |
3575 ;; - overlays | |
3576 (defun clone-buffer (&optional newname display-flag) | |
3577 "Create a twin copy of the current buffer. | |
3578 If NEWNAME is nil, it defaults to the current buffer's name; | |
3579 NEWNAME is modified by adding or incrementing <N> at the end as necessary. | |
3580 | |
3581 If DISPLAY-FLAG is non-nil, the new buffer is shown with `pop-to-buffer'. | |
3582 This runs the normal hook `clone-buffer-hook' in the new buffer | |
3583 after it has been set up properly in other respects." | |
3584 (interactive (list (if current-prefix-arg (read-string "Name: ")) | |
3585 t)) | |
3586 (if buffer-file-name | |
3587 (error "Cannot clone a file-visiting buffer")) | |
3588 (if (get major-mode 'no-clone) | |
3589 (error "Cannot clone a buffer in %s mode" mode-name)) | |
3590 (setq newname (or newname (buffer-name))) | |
3591 (if (string-match "<[0-9]+>\\'" newname) | |
3592 (setq newname (substring newname 0 (match-beginning 0)))) | |
3593 (let ((buf (current-buffer)) | |
3594 (ptmin (point-min)) | |
3595 (ptmax (point-max)) | |
3596 (pt (point)) | |
3597 (mk (mark t)) ;(if mark-active (mark t))) | |
3598 (modified (buffer-modified-p)) | |
3599 (mode major-mode) | |
3600 (lvars (buffer-local-variables)) | |
3601 (process (get-buffer-process (current-buffer))) | |
3602 (new (generate-new-buffer (or newname (buffer-name))))) | |
3603 (save-restriction | |
3604 (widen) | |
3605 (with-current-buffer new | |
3606 (insert-buffer-substring buf))) | |
3607 (with-current-buffer new | |
3608 (narrow-to-region ptmin ptmax) | |
3609 (goto-char pt) | |
3610 (if mk (set-mark mk)) | |
3611 (set-buffer-modified-p modified) | |
3612 | |
3613 ;; Clone the old buffer's process, if any. | |
3614 (when process (clone-process process)) | |
3615 | |
3616 ;; Now set up the major mode. | |
3617 (funcall mode) | |
3618 | |
3619 ;; Set up other local variables. | |
3620 (mapcar (lambda (v) | |
3621 (condition-case () ;in case var is read-only | |
3622 (if (symbolp v) | |
3623 (makunbound v) | |
3624 (set (make-local-variable (car v)) (cdr v))) | |
3625 (error nil))) | |
3626 lvars) | |
3627 | |
3628 ;; Run any hooks (typically set up by the major mode | |
3629 ;; for cloning to work properly). | |
3630 (run-hooks 'clone-buffer-hook)) | |
3631 (if display-flag (pop-to-buffer new)) | |
3632 new)) | |
3633 | |
3634 | |
3635 (defun clone-indirect-buffer (newname display-flag &optional norecord) | |
3636 "Create an indirect buffer that is a twin copy of the current buffer. | |
3637 | |
3638 Give the indirect buffer name NEWNAME. Interactively, read NEW-NAME | |
3639 from the minibuffer when invoked with a prefix arg. If NEWNAME is nil | |
3640 or if not called with a prefix arg, NEWNAME defaults to the current | |
3641 buffer's name. The name is modified by adding a `<N>' suffix to it | |
3642 or by incrementing the N in an existing suffix. | |
3643 | |
3644 DISPLAY-FLAG non-nil means show the new buffer with `pop-to-buffer'. | |
3645 This is always done when called interactively. | |
3646 | |
3647 Optional last arg NORECORD non-nil means do not put this buffer at the | |
3648 front of the list of recently selected ones." | |
3649 (interactive (list (if current-prefix-arg | |
3650 (read-string "BName of indirect buffer: ")) | |
3651 t)) | |
3652 (setq newname (or newname (buffer-name))) | |
3653 (if (string-match "<[0-9]+>\\'" newname) | |
3654 (setq newname (substring newname 0 (match-beginning 0)))) | |
3655 (let* ((name (generate-new-buffer-name newname)) | |
3656 (buffer (make-indirect-buffer (current-buffer) name t))) | |
3657 (when display-flag | |
3658 (pop-to-buffer buffer norecord)) | |
3659 buffer)) | |
3660 | |
3661 | |
3662 (defun clone-indirect-buffer-other-window (buffer &optional norecord) | |
3663 "Create an indirect buffer that is a twin copy of BUFFER. | |
3664 Select the new buffer in another window. | |
3665 Optional second arg NORECORD non-nil means do not put this buffer at | |
3666 the front of the list of recently selected ones." | |
3667 (interactive "bClone buffer in other window: ") | |
3668 (let ((pop-up-windows t)) | |
3669 (set-buffer buffer) | |
3670 (clone-indirect-buffer nil t norecord))) | |
3671 | |
3672 ;; END SYNCHED WITH FSF 21.2. | |
3867 | 3673 |
3868 | 3674 |
3869 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3675 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3870 ;; case changing code ;; | 3676 ;; case changing code ;; |
3871 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 3677 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |