Mercurial > emacs
comparison src/callint.c @ 73441:82ed0adffca9
* callint.c (callint_message): Convert to a Lisp string.
(syms_of_callint): Initialize it.
(callint_message_size): Var deleted.
(Fcall_interactively): Use Fformat instead of doprnt to construct
prompt string.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Thu, 19 Oct 2006 14:13:52 +0000 |
parents | 6d481bdb9779 |
children | 4c1d868b634b 034f67f59091 7eeafaaa9eab |
comparison
equal
deleted
inserted
replaced
73440:334af48d9710 | 73441:82ed0adffca9 |
---|---|
56 static Lisp_Object preserved_fns; | 56 static Lisp_Object preserved_fns; |
57 | 57 |
58 /* Marker used within call-interactively to refer to point. */ | 58 /* Marker used within call-interactively to refer to point. */ |
59 static Lisp_Object point_marker; | 59 static Lisp_Object point_marker; |
60 | 60 |
61 /* Buffer for the prompt text used in Fcall_interactively. */ | 61 /* String for the prompt text used in Fcall_interactively. */ |
62 static char *callint_message; | 62 static Lisp_Object callint_message; |
63 | |
64 /* Allocated length of that buffer. */ | |
65 static int callint_message_size; | |
66 | 63 |
67 /* ARGSUSED */ | 64 /* ARGSUSED */ |
68 DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, | 65 DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, |
69 doc: /* Specify a way of parsing arguments for interactive use of a function. | 66 doc: /* Specify a way of parsing arguments for interactive use of a function. |
70 For example, write | 67 For example, write |
264 `this-command-keys-vector' is used. */) | 261 `this-command-keys-vector' is used. */) |
265 (function, record_flag, keys) | 262 (function, record_flag, keys) |
266 Lisp_Object function, record_flag, keys; | 263 Lisp_Object function, record_flag, keys; |
267 { | 264 { |
268 Lisp_Object *args, *visargs; | 265 Lisp_Object *args, *visargs; |
269 unsigned char **argstrings; | |
270 Lisp_Object fun; | 266 Lisp_Object fun; |
271 Lisp_Object specs; | 267 Lisp_Object specs; |
272 Lisp_Object filter_specs; | 268 Lisp_Object filter_specs; |
273 Lisp_Object teml; | 269 Lisp_Object teml; |
274 Lisp_Object up_event; | 270 Lisp_Object up_event; |
490 } | 486 } |
491 count = j; | 487 count = j; |
492 | 488 |
493 args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); | 489 args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); |
494 visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); | 490 visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); |
495 argstrings = (unsigned char **) alloca ((count + 1) * sizeof (char *)); | |
496 varies = (int *) alloca ((count + 1) * sizeof (int)); | 491 varies = (int *) alloca ((count + 1) * sizeof (int)); |
497 | 492 |
498 for (i = 0; i < (count + 1); i++) | 493 for (i = 0; i < (count + 1); i++) |
499 { | 494 { |
500 args[i] = Qnil; | 495 args[i] = Qnil; |
514 { | 509 { |
515 strncpy (prompt1, tem + 1, sizeof prompt1 - 1); | 510 strncpy (prompt1, tem + 1, sizeof prompt1 - 1); |
516 prompt1[sizeof prompt1 - 1] = 0; | 511 prompt1[sizeof prompt1 - 1] = 0; |
517 tem1 = (char *) index (prompt1, '\n'); | 512 tem1 = (char *) index (prompt1, '\n'); |
518 if (tem1) *tem1 = 0; | 513 if (tem1) *tem1 = 0; |
519 /* Fill argstrings with a vector of C strings | 514 |
520 corresponding to the Lisp strings in visargs. */ | 515 visargs[0] = build_string (prompt1); |
521 for (j = 1; j < i; j++) | 516 if (index (prompt1, '%')) |
522 argstrings[j] | 517 callint_message = Fformat (i, visargs); |
523 = (EQ (visargs[j], Qnil) | 518 else |
524 ? (unsigned char *) "" | 519 callint_message = visargs[0]; |
525 : SDATA (visargs[j])); | |
526 | |
527 /* Process the format-string in prompt1, putting the output | |
528 into callint_message. Make callint_message bigger if necessary. | |
529 We don't use a buffer on the stack, because the contents | |
530 need to stay stable for a while. */ | |
531 while (1) | |
532 { | |
533 int nchars = doprnt (callint_message, callint_message_size, | |
534 prompt1, (char *)0, | |
535 j - 1, (char **) argstrings + 1); | |
536 if (nchars < callint_message_size - 1) | |
537 break; | |
538 callint_message_size *= 2; | |
539 callint_message | |
540 = (char *) xrealloc (callint_message, callint_message_size); | |
541 } | |
542 | 520 |
543 switch (*tem) | 521 switch (*tem) |
544 { | 522 { |
545 case 'a': /* Symbol defined as a function */ | 523 case 'a': /* Symbol defined as a function */ |
546 visargs[i] = Fcompleting_read (build_string (callint_message), | 524 visargs[i] = Fcompleting_read (callint_message, |
547 Vobarray, Qfboundp, Qt, | 525 Vobarray, Qfboundp, Qt, |
548 Qnil, Qnil, Qnil, Qnil); | 526 Qnil, Qnil, Qnil, Qnil); |
549 /* Passing args[i] directly stimulates compiler bug */ | 527 /* Passing args[i] directly stimulates compiler bug */ |
550 teml = visargs[i]; | 528 teml = visargs[i]; |
551 args[i] = Fintern (teml, Qnil); | 529 args[i] = Fintern (teml, Qnil); |
553 | 531 |
554 case 'b': /* Name of existing buffer */ | 532 case 'b': /* Name of existing buffer */ |
555 args[i] = Fcurrent_buffer (); | 533 args[i] = Fcurrent_buffer (); |
556 if (EQ (selected_window, minibuf_window)) | 534 if (EQ (selected_window, minibuf_window)) |
557 args[i] = Fother_buffer (args[i], Qnil, Qnil); | 535 args[i] = Fother_buffer (args[i], Qnil, Qnil); |
558 args[i] = Fread_buffer (build_string (callint_message), args[i], Qt); | 536 args[i] = Fread_buffer (callint_message, args[i], Qt); |
559 break; | 537 break; |
560 | 538 |
561 case 'B': /* Name of buffer, possibly nonexistent */ | 539 case 'B': /* Name of buffer, possibly nonexistent */ |
562 args[i] = Fread_buffer (build_string (callint_message), | 540 args[i] = Fread_buffer (callint_message, |
563 Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), | 541 Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), |
564 Qnil); | 542 Qnil); |
565 break; | 543 break; |
566 | 544 |
567 case 'c': /* Character */ | 545 case 'c': /* Character */ |
568 args[i] = Fread_char (build_string (callint_message), Qnil, Qnil); | 546 args[i] = Fread_char (callint_message, Qnil, Qnil); |
569 message1_nolog ((char *) 0); | 547 message1_nolog ((char *) 0); |
570 /* Passing args[i] directly stimulates compiler bug */ | 548 /* Passing args[i] directly stimulates compiler bug */ |
571 teml = args[i]; | 549 teml = args[i]; |
572 visargs[i] = Fchar_to_string (teml); | 550 visargs[i] = Fchar_to_string (teml); |
573 break; | 551 break; |
574 | 552 |
575 case 'C': /* Command: symbol with interactive function */ | 553 case 'C': /* Command: symbol with interactive function */ |
576 visargs[i] = Fcompleting_read (build_string (callint_message), | 554 visargs[i] = Fcompleting_read (callint_message, |
577 Vobarray, Qcommandp, | 555 Vobarray, Qcommandp, |
578 Qt, Qnil, Qnil, Qnil, Qnil); | 556 Qt, Qnil, Qnil, Qnil, Qnil); |
579 /* Passing args[i] directly stimulates compiler bug */ | 557 /* Passing args[i] directly stimulates compiler bug */ |
580 teml = visargs[i]; | 558 teml = visargs[i]; |
581 args[i] = Fintern (teml, Qnil); | 559 args[i] = Fintern (teml, Qnil); |
587 /* visargs[i] = Qnil; */ | 565 /* visargs[i] = Qnil; */ |
588 varies[i] = 1; | 566 varies[i] = 1; |
589 break; | 567 break; |
590 | 568 |
591 case 'D': /* Directory name. */ | 569 case 'D': /* Directory name. */ |
592 args[i] = Fread_file_name (build_string (callint_message), Qnil, | 570 args[i] = Fread_file_name (callint_message, Qnil, |
593 current_buffer->directory, Qlambda, Qnil, | 571 current_buffer->directory, Qlambda, Qnil, |
594 Qfile_directory_p); | 572 Qfile_directory_p); |
595 break; | 573 break; |
596 | 574 |
597 case 'f': /* Existing file name. */ | 575 case 'f': /* Existing file name. */ |
598 args[i] = Fread_file_name (build_string (callint_message), | 576 args[i] = Fread_file_name (callint_message, |
599 Qnil, Qnil, Qlambda, Qnil, Qnil); | 577 Qnil, Qnil, Qlambda, Qnil, Qnil); |
600 break; | 578 break; |
601 | 579 |
602 case 'F': /* Possibly nonexistent file name. */ | 580 case 'F': /* Possibly nonexistent file name. */ |
603 args[i] = Fread_file_name (build_string (callint_message), | 581 args[i] = Fread_file_name (callint_message, |
604 Qnil, Qnil, Qnil, Qnil, Qnil); | 582 Qnil, Qnil, Qnil, Qnil, Qnil); |
605 break; | 583 break; |
606 | 584 |
607 case 'G': /* Possibly nonexistent file name, | 585 case 'G': /* Possibly nonexistent file name, |
608 default to directory alone. */ | 586 default to directory alone. */ |
609 args[i] = Fread_file_name (build_string (callint_message), | 587 args[i] = Fread_file_name (callint_message, |
610 Qnil, Qnil, Qnil, build_string (""), Qnil); | 588 Qnil, Qnil, Qnil, build_string (""), Qnil); |
611 break; | 589 break; |
612 | 590 |
613 case 'i': /* Ignore an argument -- Does not do I/O */ | 591 case 'i': /* Ignore an argument -- Does not do I/O */ |
614 varies[i] = -1; | 592 varies[i] = -1; |
616 | 594 |
617 case 'k': /* Key sequence. */ | 595 case 'k': /* Key sequence. */ |
618 { | 596 { |
619 int speccount1 = SPECPDL_INDEX (); | 597 int speccount1 = SPECPDL_INDEX (); |
620 specbind (Qcursor_in_echo_area, Qt); | 598 specbind (Qcursor_in_echo_area, Qt); |
621 args[i] = Fread_key_sequence (build_string (callint_message), | 599 args[i] = Fread_key_sequence (callint_message, |
622 Qnil, Qnil, Qnil, Qnil); | 600 Qnil, Qnil, Qnil, Qnil); |
623 unbind_to (speccount1, Qnil); | 601 unbind_to (speccount1, Qnil); |
624 teml = args[i]; | 602 teml = args[i]; |
625 visargs[i] = Fkey_description (teml, Qnil); | 603 visargs[i] = Fkey_description (teml, Qnil); |
626 | 604 |
644 | 622 |
645 case 'K': /* Key sequence to be defined. */ | 623 case 'K': /* Key sequence to be defined. */ |
646 { | 624 { |
647 int speccount1 = SPECPDL_INDEX (); | 625 int speccount1 = SPECPDL_INDEX (); |
648 specbind (Qcursor_in_echo_area, Qt); | 626 specbind (Qcursor_in_echo_area, Qt); |
649 args[i] = Fread_key_sequence (build_string (callint_message), | 627 args[i] = Fread_key_sequence (callint_message, |
650 Qnil, Qt, Qnil, Qnil); | 628 Qnil, Qt, Qnil, Qnil); |
651 teml = args[i]; | 629 teml = args[i]; |
652 visargs[i] = Fkey_description (teml, Qnil); | 630 visargs[i] = Fkey_description (teml, Qnil); |
653 unbind_to (speccount1, Qnil); | 631 unbind_to (speccount1, Qnil); |
654 | 632 |
704 varies[i] = 2; | 682 varies[i] = 2; |
705 break; | 683 break; |
706 | 684 |
707 case 'M': /* String read via minibuffer with | 685 case 'M': /* String read via minibuffer with |
708 inheriting the current input method. */ | 686 inheriting the current input method. */ |
709 args[i] = Fread_string (build_string (callint_message), | 687 args[i] = Fread_string (callint_message, |
710 Qnil, Qnil, Qnil, Qt); | 688 Qnil, Qnil, Qnil, Qt); |
711 break; | 689 break; |
712 | 690 |
713 case 'N': /* Prefix arg, else number from minibuffer */ | 691 case 'N': /* Prefix arg, else number from minibuffer */ |
714 if (!NILP (prefix_arg)) | 692 if (!NILP (prefix_arg)) |
724 message ("Please enter a number."); | 702 message ("Please enter a number."); |
725 sit_for (make_number (1), 0, 0); | 703 sit_for (make_number (1), 0, 0); |
726 } | 704 } |
727 first = 0; | 705 first = 0; |
728 | 706 |
729 tem = Fread_from_minibuffer (build_string (callint_message), | 707 tem = Fread_from_minibuffer (callint_message, |
730 Qnil, Qnil, Qnil, Qnil, Qnil, | 708 Qnil, Qnil, Qnil, Qnil, Qnil, |
731 Qnil); | 709 Qnil); |
732 if (! STRINGP (tem) || SCHARS (tem) == 0) | 710 if (! STRINGP (tem) || SCHARS (tem) == 0) |
733 args[i] = Qnil; | 711 args[i] = Qnil; |
734 else | 712 else |
735 args[i] = Fread (tem); | 713 args[i] = Fread (tem); |
736 } | 714 } |
737 while (! NUMBERP (args[i])); | 715 while (! NUMBERP (args[i])); |
738 } | 716 } |
739 visargs[i] = last_minibuf_string; | 717 visargs[i] = args[i]; |
740 break; | 718 break; |
741 | 719 |
742 case 'P': /* Prefix arg in raw form. Does no I/O. */ | 720 case 'P': /* Prefix arg in raw form. Does no I/O. */ |
743 args[i] = prefix_arg; | 721 args[i] = prefix_arg; |
744 /* visargs[i] = Qnil; */ | 722 /* visargs[i] = Qnil; */ |
764 varies[i] = 4; | 742 varies[i] = 4; |
765 break; | 743 break; |
766 | 744 |
767 case 's': /* String read via minibuffer without | 745 case 's': /* String read via minibuffer without |
768 inheriting the current input method. */ | 746 inheriting the current input method. */ |
769 args[i] = Fread_string (build_string (callint_message), | 747 args[i] = Fread_string (callint_message, |
770 Qnil, Qnil, Qnil, Qnil); | 748 Qnil, Qnil, Qnil, Qnil); |
771 break; | 749 break; |
772 | 750 |
773 case 'S': /* Any symbol. */ | 751 case 'S': /* Any symbol. */ |
774 visargs[i] = Fread_string (build_string (callint_message), | 752 visargs[i] = Fread_string (callint_message, |
775 Qnil, Qnil, Qnil, Qnil); | 753 Qnil, Qnil, Qnil, Qnil); |
776 /* Passing args[i] directly stimulates compiler bug */ | 754 /* Passing args[i] directly stimulates compiler bug */ |
777 teml = visargs[i]; | 755 teml = visargs[i]; |
778 args[i] = Fintern (teml, Qnil); | 756 args[i] = Fintern (teml, Qnil); |
779 break; | 757 break; |
780 | 758 |
781 case 'v': /* Variable name: symbol that is | 759 case 'v': /* Variable name: symbol that is |
782 user-variable-p. */ | 760 user-variable-p. */ |
783 args[i] = Fread_variable (build_string (callint_message), Qnil); | 761 args[i] = Fread_variable (callint_message, Qnil); |
784 visargs[i] = last_minibuf_string; | 762 visargs[i] = last_minibuf_string; |
785 break; | 763 break; |
786 | 764 |
787 case 'x': /* Lisp expression read but not evaluated */ | 765 case 'x': /* Lisp expression read but not evaluated */ |
788 args[i] = Fread_minibuffer (build_string (callint_message), Qnil); | 766 args[i] = Fread_minibuffer (callint_message, Qnil); |
789 visargs[i] = last_minibuf_string; | 767 visargs[i] = last_minibuf_string; |
790 break; | 768 break; |
791 | 769 |
792 case 'X': /* Lisp expression read and evaluated */ | 770 case 'X': /* Lisp expression read and evaluated */ |
793 args[i] = Feval_minibuffer (build_string (callint_message), Qnil); | 771 args[i] = Feval_minibuffer (callint_message, Qnil); |
794 visargs[i] = last_minibuf_string; | 772 visargs[i] = last_minibuf_string; |
795 break; | 773 break; |
796 | 774 |
797 case 'Z': /* Coding-system symbol, or ignore the | 775 case 'Z': /* Coding-system symbol, or ignore the |
798 argument if no prefix */ | 776 argument if no prefix */ |
802 varies[i] = -1; | 780 varies[i] = -1; |
803 } | 781 } |
804 else | 782 else |
805 { | 783 { |
806 args[i] | 784 args[i] |
807 = Fread_non_nil_coding_system (build_string (callint_message)); | 785 = Fread_non_nil_coding_system (callint_message); |
808 visargs[i] = last_minibuf_string; | 786 visargs[i] = last_minibuf_string; |
809 } | 787 } |
810 break; | 788 break; |
811 | 789 |
812 case 'z': /* Coding-system symbol or nil */ | 790 case 'z': /* Coding-system symbol or nil */ |
813 args[i] = Fread_coding_system (build_string (callint_message), Qnil); | 791 args[i] = Fread_coding_system (callint_message, Qnil); |
814 visargs[i] = last_minibuf_string; | 792 visargs[i] = last_minibuf_string; |
815 break; | 793 break; |
816 | 794 |
817 /* We have a case for `+' so we get an error | 795 /* We have a case for `+' so we get an error |
818 if anyone tries to define one here. */ | 796 if anyone tries to define one here. */ |
913 syms_of_callint () | 891 syms_of_callint () |
914 { | 892 { |
915 point_marker = Fmake_marker (); | 893 point_marker = Fmake_marker (); |
916 staticpro (&point_marker); | 894 staticpro (&point_marker); |
917 | 895 |
896 callint_message = Qnil; | |
897 staticpro (&callint_message); | |
898 | |
918 preserved_fns = Fcons (intern ("region-beginning"), | 899 preserved_fns = Fcons (intern ("region-beginning"), |
919 Fcons (intern ("region-end"), | 900 Fcons (intern ("region-end"), |
920 Fcons (intern ("point"), | 901 Fcons (intern ("point"), |
921 Fcons (intern ("mark"), Qnil)))); | 902 Fcons (intern ("mark"), Qnil)))); |
922 staticpro (&preserved_fns); | 903 staticpro (&preserved_fns); |
952 staticpro (&Qenable_recursive_minibuffers); | 933 staticpro (&Qenable_recursive_minibuffers); |
953 | 934 |
954 Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook"); | 935 Qmouse_leave_buffer_hook = intern ("mouse-leave-buffer-hook"); |
955 staticpro (&Qmouse_leave_buffer_hook); | 936 staticpro (&Qmouse_leave_buffer_hook); |
956 | 937 |
957 callint_message_size = 100; | |
958 callint_message = (char *) xmalloc (callint_message_size); | |
959 | |
960 | |
961 DEFVAR_KBOARD ("prefix-arg", Vprefix_arg, | 938 DEFVAR_KBOARD ("prefix-arg", Vprefix_arg, |
962 doc: /* The value of the prefix argument for the next editing command. | 939 doc: /* The value of the prefix argument for the next editing command. |
963 It may be a number, or the symbol `-' for just a minus sign as arg, | 940 It may be a number, or the symbol `-' for just a minus sign as arg, |
964 or a list whose car is a number for just one or more C-u's | 941 or a list whose car is a number for just one or more C-u's |
965 or nil if no argument has been specified. | 942 or nil if no argument has been specified. |