aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-06-03 11:25:01 +0800
committerPo Lu2023-06-03 11:25:01 +0800
commitc308accc6d0f45cc64bb664fcc43a33a7ab015b3 (patch)
tree4326e2545a391b340322b6d4f5a02cf2b7c4a2da
parenta696ed5c30fb9a7ba2d37f0e691de17872fdab16 (diff)
downloademacs-c308accc6d0f45cc64bb664fcc43a33a7ab015b3.tar.gz
emacs-c308accc6d0f45cc64bb664fcc43a33a7ab015b3.zip
Behave correctly when IMEs commit or compose text with active mark
* src/textconv.c (really_commit_text) (really_set_composing_text): Delete text between mark and point if the mark is active. Don't record changes if the text is empty.
-rw-r--r--src/textconv.c104
1 files changed, 79 insertions, 25 deletions
diff --git a/src/textconv.c b/src/textconv.c
index e082eb6ee22..0716cf7edbb 100644
--- a/src/textconv.c
+++ b/src/textconv.c
@@ -545,7 +545,10 @@ restore_selected_window (Lisp_Object window)
545 545
546/* Commit the given text in the composing region. If there is no 546/* Commit the given text in the composing region. If there is no
547 composing region, then insert the text after F's selected window's 547 composing region, then insert the text after F's selected window's
548 last point instead. Finally, remove the composing region. 548 last point instead, unless the mark is active. Finally, remove the
549 composing region.
550
551 If the mark is active, delete the text between mark and point.
549 552
550 Then, move point to POSITION relative to TEXT. If POSITION is 553 Then, move point to POSITION relative to TEXT. If POSITION is
551 greater than zero, it is relative to the character at the end of 554 greater than zero, it is relative to the character at the end of
@@ -556,7 +559,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
556 Lisp_Object text) 559 Lisp_Object text)
557{ 560{
558 specpdl_ref count; 561 specpdl_ref count;
559 ptrdiff_t wanted, start, end; 562 ptrdiff_t wanted, start, end, mark;
560 struct window *w; 563 struct window *w;
561 564
562 /* If F's old selected window is no longer live, fail. */ 565 /* If F's old selected window is no longer live, fail. */
@@ -572,28 +575,48 @@ really_commit_text (struct frame *f, EMACS_INT position,
572 redisplay. */ 575 redisplay. */
573 select_window (f->old_selected_window, Qt); 576 select_window (f->old_selected_window, Qt);
574 577
575 /* Now detect whether or not there is a composing region. 578 /* Now detect whether or not there is a composing or active region.
576 If there is, then replace it with TEXT. Don't do that 579 If there is, then replace it with TEXT. Don't do that
577 otherwise. */ 580 otherwise. */
578 581
579 if (MARKERP (f->conversion.compose_region_start)) 582 mark = get_mark ();
583 if (MARKERP (f->conversion.compose_region_start) || mark != -1)
580 { 584 {
581 /* Replace its contents. */ 585 /* Replace its contents. Set START and END to the start and end
582 start = marker_position (f->conversion.compose_region_start); 586 of the composing region if it exists. */
583 end = marker_position (f->conversion.compose_region_end); 587
588 if (MARKERP (f->conversion.compose_region_start))
589 {
590 start = marker_position (f->conversion.compose_region_start);
591 end = marker_position (f->conversion.compose_region_end);
592 }
593 else
594 {
595 /* Otherwise, set it to the start and end of the region. */
596 start = min (mark, PT);
597 end = max (mark, PT);
598 }
599
600 /* Now delete whatever needs to go. */
601
584 del_range (start, end); 602 del_range (start, end);
585 record_buffer_change (start, start, Qnil); 603 record_buffer_change (start, start, Qnil);
586 Finsert (1, &text);
587 record_buffer_change (start, PT, text);
588 604
589 /* Move to a the position specified in POSITION. If POSITION is 605 /* Don't record changes if TEXT is empty. */
590 less than zero, it is relative to the start of the text that 606
591 was inserted. */ 607 if (SCHARS (text))
608 {
609 Finsert (1, &text);
610 record_buffer_change (start, PT, text);
611 }
612
613 /* Move to a the position specified in POSITION. */
592 614
593 if (position <= 0) 615 if (position <= 0)
594 { 616 {
595 wanted 617 /* If POSITION is less than zero, it is relative to the
596 = marker_position (f->conversion.compose_region_start); 618 start of the text that was inserted. */
619 wanted = start;
597 620
598 if (INT_ADD_WRAPV (wanted, position, &wanted) 621 if (INT_ADD_WRAPV (wanted, position, &wanted)
599 || wanted < BEGV) 622 || wanted < BEGV)
@@ -608,9 +631,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
608 { 631 {
609 /* Otherwise, it is relative to the last character in 632 /* Otherwise, it is relative to the last character in
610 TEXT. */ 633 TEXT. */
611 634 wanted = PT;
612 wanted
613 = marker_position (f->conversion.compose_region_end);
614 635
615 if (INT_ADD_WRAPV (wanted, position - 1, &wanted) 636 if (INT_ADD_WRAPV (wanted, position - 1, &wanted)
616 || wanted > ZV) 637 || wanted > ZV)
@@ -642,8 +663,14 @@ really_commit_text (struct frame *f, EMACS_INT position,
642 /* Otherwise, move the text and point to an appropriate 663 /* Otherwise, move the text and point to an appropriate
643 location. */ 664 location. */
644 wanted = PT; 665 wanted = PT;
645 Finsert (1, &text); 666
646 record_buffer_change (wanted, PT, text); 667 /* Don't record changes if TEXT is empty. */
668
669 if (SCHARS (text))
670 {
671 Finsert (1, &text);
672 record_buffer_change (start, PT, text);
673 }
647 674
648 if (position <= 0) 675 if (position <= 0)
649 { 676 {
@@ -737,6 +764,32 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
737 764
738 if (!MARKERP (f->conversion.compose_region_start)) 765 if (!MARKERP (f->conversion.compose_region_start))
739 { 766 {
767 /* Set START and END. */
768 start = PT;
769 wanted = end = get_mark ();
770
771 /* If END is -1, set it to start. */
772
773 if (end == -1)
774 end = start;
775 else
776 {
777 /* Now sort start and end. */
778 start = min (start, end);
779 end = max (PT, wanted);
780 }
781
782 /* If END is not the same as start, delete the text in
783 between. */
784
785 if (end != start)
786 {
787 del_range (start, end);
788 set_point (start);
789 record_buffer_change (start, start, Qnil);
790 }
791
792 /* Now set the markers which denote the composition region. */
740 f->conversion.compose_region_start 793 f->conversion.compose_region_start
741 = build_marker (current_buffer, PT, PT_BYTE); 794 = build_marker (current_buffer, PT, PT_BYTE);
742 f->conversion.compose_region_end 795 f->conversion.compose_region_end
@@ -744,8 +797,6 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
744 797
745 Fset_marker_insertion_type (f->conversion.compose_region_end, 798 Fset_marker_insertion_type (f->conversion.compose_region_end,
746 Qt); 799 Qt);
747
748 start = PT;
749 } 800 }
750 else 801 else
751 { 802 {
@@ -1368,6 +1419,9 @@ end_batch_edit (struct frame *f, unsigned long counter)
1368/* Insert the specified STRING into F's current buffer's composition 1419/* Insert the specified STRING into F's current buffer's composition
1369 region, and set point to POSITION relative to STRING. 1420 region, and set point to POSITION relative to STRING.
1370 1421
1422 If there is no composition region, use the active region instead.
1423 If that doesn't exist either, insert STRING after point.
1424
1371 COUNTER means the same as in `start_batch_edit'. */ 1425 COUNTER means the same as in `start_batch_edit'. */
1372 1426
1373void 1427void
@@ -1415,11 +1469,11 @@ finish_composing_text (struct frame *f, unsigned long counter,
1415/* Insert the given STRING and make it the currently active 1469/* Insert the given STRING and make it the currently active
1416 composition. 1470 composition.
1417 1471
1418 If there is currently no composing region, then the new value of 1472 If there is currently no composing or active region, then the new
1419 point is used as the composing region. 1473 value of point is used as the composing region.
1420 1474
1421 Then, the composing region is replaced with the text in the 1475 Then, the composing or active region is replaced with the text in
1422 specified string. 1476 the specified string.
1423 1477
1424 Finally, move point to new_point, which is relative to either the 1478 Finally, move point to new_point, which is relative to either the
1425 start or the end of OBJECT depending on whether or not it is less 1479 start or the end of OBJECT depending on whether or not it is less