comparison src/event-stream.c @ 5803:b79e1e02bf01

Preserve extent information in the command builder code. src/ChangeLog addition: 2014-07-14 Aidan Kehoe <kehoea@parhasard.net> * event-stream.c: * event-stream.c (mark_command_builder): * event-stream.c (finalize_command_builder): Removed. * event-stream.c (allocate_command_builder): * event-stream.c (free_command_builder): Removed. Use free_normal_lisp_object() instead. * event-stream.c (echo_key_event): * event-stream.c (regenerate_echo_keys_from_this_command_keys): Detach all extents here. * event-stream.c (maybe_echo_keys): * event-stream.c (reset_key_echo): * event-stream.c (execute_help_form): * event-stream.c (Fnext_event): * event-stream.c (command_builder_find_leaf_no_jit_binding): * event-stream.c (command_builder_find_leaf): * event-stream.c (lookup_command_event): * events.h (struct command_builder): Move the command builder's echo_buf to being a Lisp string rather than a malloced Ibyte array. This allows passing through extent information, which was previously dropped. It also simplifies the allocation and release code for the command builder. Rename echo_buf_index to echo_buf_fill_pointer, better reflecting its function. Don't rely on zero-termination (something not particularly compatible with Lisp-level code) when showing a substring of echo_buf that differs from that designated by echo_buf_fill_pointer, keep a separate counter instead and use that. * minibuf.c: * minibuf.c (echo_area_append): Use the new START and END keyword arguments to #'append-message, rather than consing a new string for basically every #'next-event prompt displayed. test/ChangeLog addition: 2014-07-14 Aidan Kehoe <kehoea@parhasard.net> * automated/extent-tests.el: Check that extent information is passed through to the echo area correctly with #'next-event's PROMPT argument. lisp/ChangeLog addition: 2014-07-14 Aidan Kehoe <kehoea@parhasard.net> * simple.el (raw-append-message): Use #'write-sequence in this, take its START and END keyword arguments, so our callers don't have to cons as much. * simple.el (append-message): Pass through START and END here.
author Aidan Kehoe <kehoea@parhasard.net>
date Mon, 14 Jul 2014 13:42:42 +0100
parents 0e9f791cc655
children 75435be92103
comparison
equal deleted inserted replaced
5802:236e4afc565d 5803:b79e1e02bf01
79 #include "buffer.h" 79 #include "buffer.h"
80 #include "commands.h" 80 #include "commands.h"
81 #include "device-impl.h" 81 #include "device-impl.h"
82 #include "elhash.h" 82 #include "elhash.h"
83 #include "events.h" 83 #include "events.h"
84 #include "extents.h"
84 #include "frame-impl.h" 85 #include "frame-impl.h"
85 #include "insdel.h" /* for buffer_reset_changes */ 86 #include "insdel.h" /* for buffer_reset_changes */
86 #include "keymap.h" 87 #include "keymap.h"
87 #include "lstream.h" 88 #include "lstream.h"
88 #include "macros.h" /* for defining_keyboard_macro */ 89 #include "macros.h" /* for defining_keyboard_macro */
334 { XD_LISP_OBJECT, offsetof (struct command_builder, current_events) }, 335 { XD_LISP_OBJECT, offsetof (struct command_builder, current_events) },
335 { XD_LISP_OBJECT, offsetof (struct command_builder, most_current_event) }, 336 { XD_LISP_OBJECT, offsetof (struct command_builder, most_current_event) },
336 { XD_LISP_OBJECT, offsetof (struct command_builder, last_non_munged_event) }, 337 { XD_LISP_OBJECT, offsetof (struct command_builder, last_non_munged_event) },
337 { XD_LISP_OBJECT, offsetof (struct command_builder, console) }, 338 { XD_LISP_OBJECT, offsetof (struct command_builder, console) },
338 { XD_LISP_OBJECT_ARRAY, offsetof (struct command_builder, first_mungeable_event), 2 }, 339 { XD_LISP_OBJECT_ARRAY, offsetof (struct command_builder, first_mungeable_event), 2 },
340 { XD_LISP_OBJECT, offsetof (struct command_builder, echo_buf) },
339 { XD_END } 341 { XD_END }
340 }; 342 };
341 343
342 static Lisp_Object 344 static Lisp_Object
343 mark_command_builder (Lisp_Object obj) 345 mark_command_builder (Lisp_Object obj)
346 mark_object (builder->current_events); 348 mark_object (builder->current_events);
347 mark_object (builder->most_current_event); 349 mark_object (builder->most_current_event);
348 mark_object (builder->last_non_munged_event); 350 mark_object (builder->last_non_munged_event);
349 mark_object (builder->first_mungeable_event[0]); 351 mark_object (builder->first_mungeable_event[0]);
350 mark_object (builder->first_mungeable_event[1]); 352 mark_object (builder->first_mungeable_event[1]);
353 mark_object (builder->echo_buf);
351 return builder->console; 354 return builder->console;
352 }
353
354 static void
355 finalize_command_builder (Lisp_Object obj)
356 {
357 struct command_builder *b = XCOMMAND_BUILDER (obj);
358 if (b->echo_buf)
359 {
360 xfree (b->echo_buf);
361 b->echo_buf = 0;
362 }
363 } 355 }
364 356
365 DEFINE_NODUMP_LISP_OBJECT ("command-builder", command_builder, 357 DEFINE_NODUMP_LISP_OBJECT ("command-builder", command_builder,
366 mark_command_builder, 358 mark_command_builder,
367 internal_object_printer, 359 internal_object_printer, 0, 0, 0,
368 finalize_command_builder, 0, 0,
369 command_builder_description, 360 command_builder_description,
370 struct command_builder); 361 struct command_builder);
371 362
372 static void 363 static void
373 reset_command_builder_event_chain (struct command_builder *builder) 364 reset_command_builder_event_chain (struct command_builder *builder)
387 378
388 builder->console = console; 379 builder->console = console;
389 reset_command_builder_event_chain (builder); 380 reset_command_builder_event_chain (builder);
390 if (with_echo_buf) 381 if (with_echo_buf)
391 { 382 {
392 /* #### This badly needs to be turned into a Dynarr */ 383 builder->echo_buf = make_uninit_string (300 * MAX_ICHAR_LEN);
393 builder->echo_buf_length = 300; /* #### Kludge */
394 builder->echo_buf = xnew_array (Ibyte, builder->echo_buf_length);
395 builder->echo_buf[0] = 0;
396 } 384 }
397 else 385 else
398 { 386 {
399 builder->echo_buf_length = 0; 387 builder->echo_buf = Qnil;
400 builder->echo_buf = NULL; 388 }
401 } 389 builder->echo_buf_fill_pointer = builder->echo_buf_end = -1;
402 builder->echo_buf_index = -1;
403 builder->self_insert_countdown = 0; 390 builder->self_insert_countdown = 0;
404 391
405 return builder_obj; 392 return builder_obj;
406 } 393 }
407 394
444 431
445 return wrap_command_builder (new_buildings); 432 return wrap_command_builder (new_buildings);
446 } 433 }
447 434
448 static void 435 static void
449 free_command_builder (struct command_builder *builder)
450 {
451 if (builder->echo_buf)
452 {
453 xfree (builder->echo_buf);
454 builder->echo_buf = NULL;
455 }
456 free_normal_lisp_object (wrap_command_builder (builder));
457 }
458
459 static void
460 command_builder_append_event (struct command_builder *builder, 436 command_builder_append_event (struct command_builder *builder,
461 Lisp_Object event) 437 Lisp_Object event)
462 { 438 {
463 assert (EVENTP (event)); 439 assert (EVENTP (event));
464 440
658 echo_key_event (struct command_builder *command_builder, 634 echo_key_event (struct command_builder *command_builder,
659 Lisp_Object event) 635 Lisp_Object event)
660 { 636 {
661 /* This function can GC */ 637 /* This function can GC */
662 DECLARE_EISTRING_MALLOC (buf); 638 DECLARE_EISTRING_MALLOC (buf);
663 Bytecount buf_index = command_builder->echo_buf_index; 639 Bytecount buf_fill_pointer = command_builder->echo_buf_fill_pointer;
664 Ibyte *e;
665 Bytecount len; 640 Bytecount len;
666 641
667 if (buf_index < 0) 642 if (buf_fill_pointer < 0)
668 { 643 {
669 buf_index = 0; /* We're echoing now */ 644 buf_fill_pointer = 0;
670 clear_echo_area (selected_frame (), Qnil, 0); 645 clear_echo_area (selected_frame (), Qnil, 0);
671 } 646 }
672 647
673 format_event_object (buf, event, 1); 648 format_event_object (buf, event, 1);
674 len = eilen (buf); 649 len = eilen (buf);
675 650
676 if (len + buf_index + 4 > command_builder->echo_buf_length) 651 if (NILP (command_builder->echo_buf) ||
652 (len + buf_fill_pointer + 4 > XSTRING_LENGTH (command_builder->echo_buf)))
677 { 653 {
678 eifree (buf); 654 eifree (buf);
679 return; 655 return;
680 } 656 }
681 e = command_builder->echo_buf + buf_index; 657
682 memcpy (e, eidata (buf), len); 658 eicat_ascii (buf, " - ");
683 e += len; 659
660 memcpy (XSTRING_DATA (command_builder->echo_buf) + buf_fill_pointer,
661 eidata (buf), eilen (buf));
662 init_string_ascii_begin (command_builder->echo_buf);
663 bump_string_modiff (command_builder->echo_buf);
664 sledgehammer_check_ascii_begin (command_builder->echo_buf);
665
666 command_builder->echo_buf_end = buf_fill_pointer + eilen (buf);
667 /* *Not* including the trailing " - ". */
668 command_builder->echo_buf_fill_pointer = buf_fill_pointer + len + 1;
684 eifree (buf); 669 eifree (buf);
685
686 e[0] = ' ';
687 e[1] = '-';
688 e[2] = ' ';
689 e[3] = 0;
690
691 command_builder->echo_buf_index = buf_index + len + 1;
692 } 670 }
693 671
694 static void 672 static void
695 regenerate_echo_keys_from_this_command_keys (struct command_builder * 673 regenerate_echo_keys_from_this_command_keys (struct command_builder *
696 builder) 674 builder)
697 { 675 {
698 Lisp_Object event; 676 Lisp_Object event;
699 677
700 builder->echo_buf_index = 0; 678 builder->echo_buf_fill_pointer = builder->echo_buf_end = 0;
679 if (STRINGP (builder->echo_buf))
680 {
681 detach_all_extents (builder->echo_buf);
682 }
701 683
702 EVENT_CHAIN_LOOP (event, Vthis_command_keys) 684 EVENT_CHAIN_LOOP (event, Vthis_command_keys)
703 echo_key_event (builder, event); 685 echo_key_event (builder, event);
704 } 686 }
705 687
732 if (NILP (Fsit_for (Vecho_keystrokes, Qnil))) 714 if (NILP (Fsit_for (Vecho_keystrokes, Qnil)))
733 /* input came in, so don't echo. */ 715 /* input came in, so don't echo. */
734 goto done; 716 goto done;
735 } 717 }
736 718
737 echo_area_message (f, command_builder->echo_buf, Qnil, 0, 719 echo_area_message (f, NULL, command_builder->echo_buf, 0,
738 /* not echo_buf_index. That doesn't include 720 command_builder->echo_buf_end, Qcommand);
739 the terminating " - ". */
740 strlen ((char *) command_builder->echo_buf),
741 Qcommand);
742 } 721 }
743 722
744 done: 723 done:
745 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ 724 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */
746 unbind_to (depth); 725 unbind_to (depth);
752 { 731 {
753 /* This function can GC */ 732 /* This function can GC */
754 struct frame *f = selected_frame (); 733 struct frame *f = selected_frame ();
755 734
756 if (command_builder) 735 if (command_builder)
757 command_builder->echo_buf_index = -1; 736 {
737 command_builder->echo_buf_fill_pointer =
738 command_builder->echo_buf_end = -1;
739 }
758 740
759 if (remove_echo_area_echo) 741 if (remove_echo_area_echo)
760 clear_echo_area (f, Qcommand, 0); 742 clear_echo_area (f, Qcommand, 0);
761 } 743 }
762 744
812 Lisp_Object event) 794 Lisp_Object event)
813 { 795 {
814 /* This function can GC */ 796 /* This function can GC */
815 Lisp_Object help = Qnil; 797 Lisp_Object help = Qnil;
816 int speccount = specpdl_depth (); 798 int speccount = specpdl_depth ();
817 Bytecount buf_index = command_builder->echo_buf_index; 799 Bytecount buf_fill_pointer = command_builder->echo_buf_fill_pointer;
818 Lisp_Object echo = ((buf_index <= 0) 800 Bytecount buf_end = command_builder->echo_buf_end;
819 ? Qnil 801 Lisp_Object echo = ((buf_fill_pointer <= 0) ? Qnil
820 : make_string (command_builder->echo_buf, 802 : Fcopy_sequence (command_builder->echo_buf));
821 buf_index)); 803
822 struct gcpro gcpro1, gcpro2; 804 struct gcpro gcpro1, gcpro2;
823 GCPRO2 (echo, help); 805 GCPRO2 (echo, help);
824 806
825 record_unwind_protect (Feval, 807 record_unwind_protect (Feval,
826 list2 (Qset_window_configuration, 808 list2 (Qset_window_configuration,
854 /* Discard next key if it is a space */ 836 /* Discard next key if it is a space */
855 reset_key_echo (command_builder, 1); 837 reset_key_echo (command_builder, 1);
856 Fnext_command_event (event, Qnil); 838 Fnext_command_event (event, Qnil);
857 } 839 }
858 840
859 command_builder->echo_buf_index = buf_index; 841 command_builder->echo_buf_fill_pointer = buf_fill_pointer;
860 if (buf_index > 0) 842 command_builder->echo_buf_end = buf_end;
861 memcpy (command_builder->echo_buf, 843
862 XSTRING_DATA (echo), buf_index + 1); /* terminating 0 */ 844 if (buf_fill_pointer > 0)
845 {
846 command_builder->echo_buf = echo;
847 }
863 UNGCPRO; 848 UNGCPRO;
864 } 849 }
865 850
866 851
867 /**********************************************************************/ 852 /**********************************************************************/
2180 CHECK_LIVE_EVENT (event); 2165 CHECK_LIVE_EVENT (event);
2181 2166
2182 if (!NILP (prompt)) 2167 if (!NILP (prompt))
2183 { 2168 {
2184 Bytecount len; 2169 Bytecount len;
2170 Lisp_Object args[] = { Qnil, prompt };
2185 CHECK_STRING (prompt); 2171 CHECK_STRING (prompt);
2186 2172
2187 len = XSTRING_LENGTH (prompt); 2173 len = XSTRING_LENGTH (prompt);
2188 if (command_builder->echo_buf_length < len) 2174
2189 len = command_builder->echo_buf_length - 1; 2175 detach_all_extents (command_builder->echo_buf);
2190 memcpy (command_builder->echo_buf, XSTRING_DATA (prompt), len); 2176 if (XSTRING_LENGTH (command_builder->echo_buf) < len)
2191 command_builder->echo_buf[len] = 0; 2177 {
2192 command_builder->echo_buf_index = len; 2178 command_builder->echo_buf
2193 echo_area_message (XFRAME (CONSOLE_SELECTED_FRAME (con)), 2179 = make_uninit_string (len + 200 * MAX_ICHAR_LEN);
2194 command_builder->echo_buf, 2180 }
2195 Qnil, 0, 2181
2196 command_builder->echo_buf_index, 2182 args[0] = command_builder->echo_buf;
2197 Qcommand); 2183 Freplace (countof (args), args);
2184 copy_string_extents (command_builder->echo_buf, prompt, 0, 0,
2185 XSTRING_LENGTH (prompt));
2186 command_builder->echo_buf_fill_pointer
2187 = command_builder->echo_buf_end = len;
2188
2189 echo_area_message (XFRAME (CONSOLE_SELECTED_FRAME (con)), NULL,
2190 command_builder->echo_buf, 0,
2191 command_builder->echo_buf_end, Qcommand);
2198 } 2192 }
2199 2193
2200 start_over_and_avoid_hosage: 2194 start_over_and_avoid_hosage:
2201 2195
2202 /* If there is something in unread-command-events, simply return it. 2196 /* If there is something in unread-command-events, simply return it.
3390 if (!NILP (result)) 3384 if (!NILP (result))
3391 { 3385 {
3392 copy_command_builder (neub, builder); 3386 copy_command_builder (neub, builder);
3393 *did_munge = 1; 3387 *did_munge = 1;
3394 } 3388 }
3395 free_command_builder (neub); 3389 free_normal_lisp_object (wrap_command_builder (neub));
3396 UNGCPRO; 3390 UNGCPRO;
3397 if (!NILP (result)) 3391 if (!NILP (result))
3398 return result; 3392 return result;
3399 } 3393 }
3400 } 3394 }
3602 make_char(tolower(this_alternative))); 3596 make_char(tolower(this_alternative)));
3603 result = command_builder_find_leaf_no_jit_binding 3597 result = command_builder_find_leaf_no_jit_binding
3604 (newb, allow_misc_user_events_p, did_munge); 3598 (newb, allow_misc_user_events_p, did_munge);
3605 } 3599 }
3606 3600
3607 free_command_builder (newb); 3601 free_normal_lisp_object (wrap_command_builder (newb));
3608 UNGCPRO; 3602 UNGCPRO;
3609 3603
3610 if (!NILP (result)) 3604 if (!NILP (result))
3611 return result; 3605 return result;
3612 } 3606 }
4072 { 4066 {
4073 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); 4067 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt);
4074 if (STRINGP (prompt)) 4068 if (STRINGP (prompt))
4075 { 4069 {
4076 /* Append keymap prompt to key echo buffer */ 4070 /* Append keymap prompt to key echo buffer */
4077 int buf_index = command_builder->echo_buf_index; 4071 int buf_fill_pointer = command_builder->echo_buf_fill_pointer;
4078 Bytecount len = XSTRING_LENGTH (prompt); 4072 Bytecount len = XSTRING_LENGTH (prompt);
4079 4073
4080 if (len + buf_index + 1 <= command_builder->echo_buf_length) 4074 if (len + buf_fill_pointer + 1
4075 <= XSTRING_LENGTH (command_builder->echo_buf))
4081 { 4076 {
4082 Ibyte *echo = command_builder->echo_buf + buf_index; 4077 memcpy (XSTRING_DATA (command_builder->echo_buf)
4083 memcpy (echo, XSTRING_DATA (prompt), len); 4078 + buf_fill_pointer,
4084 echo[len] = 0; 4079 XSTRING_DATA (prompt),
4080 len);
4081 copy_string_extents (command_builder->echo_buf, prompt,
4082 buf_fill_pointer, 0, len);
4083
4084 init_string_ascii_begin (command_builder->echo_buf);
4085 bump_string_modiff (command_builder->echo_buf);
4086 sledgehammer_check_ascii_begin (command_builder->echo_buf);
4087
4088 /* Show the keymap prompt, but don't adjust the fill
4089 pointer to reflect it. */
4090 command_builder->echo_buf_end
4091 = command_builder->echo_buf_fill_pointer + len;
4085 } 4092 }
4086 maybe_echo_keys (command_builder, 1); 4093 maybe_echo_keys (command_builder, 1);
4087 } 4094 }
4088 else 4095 else
4089 maybe_echo_keys (command_builder, 0); 4096 maybe_echo_keys (command_builder, 0);
4102 #endif 4109 #endif
4103 } 4110 }
4104 else if (!NILP (leaf)) 4111 else if (!NILP (leaf))
4105 { 4112 {
4106 if (EQ (Qcommand, echo_area_status (f)) 4113 if (EQ (Qcommand, echo_area_status (f))
4107 && command_builder->echo_buf_index > 0) 4114 && command_builder->echo_buf_fill_pointer > 0)
4108 { 4115 {
4109 /* If we had been echoing keys, echo the last one (without 4116 /* If we had been echoing keys, echo the last one (without
4110 the trailing dash) and redisplay before executing the 4117 the trailing dash) and redisplay before executing the
4111 command. */ 4118 command. */
4112 command_builder->echo_buf[command_builder->echo_buf_index] = 0; 4119 command_builder->echo_buf_end =
4120 command_builder->echo_buf_fill_pointer;
4113 maybe_echo_keys (command_builder, 1); 4121 maybe_echo_keys (command_builder, 1);
4114 Fsit_for (Qzero, Qt); 4122 Fsit_for (Qzero, Qt);
4115 } 4123 }
4116 } 4124 }
4117 RETURN_UNGCPRO (leaf); 4125 RETURN_UNGCPRO (leaf);