aboutsummaryrefslogtreecommitdiffstats
path: root/src/textconv.c
diff options
context:
space:
mode:
authorPo Lu2023-02-15 22:51:44 +0800
committerPo Lu2023-02-15 22:51:44 +0800
commitcf24b61985c26cbf2e5a24cb0b64a8528aa3a9cc (patch)
treeb69f8dbb50e3e2f6f09caa05aecbee5241876f62 /src/textconv.c
parentdd7066901f67233c09f3b0409a57db7686c7ea5b (diff)
downloademacs-cf24b61985c26cbf2e5a24cb0b64a8528aa3a9cc.tar.gz
emacs-cf24b61985c26cbf2e5a24cb0b64a8528aa3a9cc.zip
Update Android port
* doc/emacs/input.texi (On-Screen Keyboards): * doc/lispref/commands.texi (Misc Events): Improve documentation of text conversion stuff. * java/org/gnu/emacs/EmacsInputConnection.java (beginBatchEdit) (endBatchEdit, commitCompletion, commitText, deleteSurroundingText) (finishComposingText, getSelectedText, getTextAfterCursor) (EmacsInputConnection, setComposingRegion, performEditorAction) (getExtractedText): Condition debug code on DEBUG_IC. * java/org/gnu/emacs/EmacsService.java (EmacsService, updateIC): Likewise. * lisp/bindings.el (global-map): * lisp/electric.el (global-map): Make `text-conversion' `analyze-text-conversion'. * lisp/progmodes/prog-mode.el (prog-mode): Enable text conversion in input methods. * lisp/simple.el (analyze-text-conversion): New function. * lisp/textmodes/text-mode.el (text-conversion-style) (text-mode): Likewise. * src/androidterm.c (android_handle_ime_event): Handle set_point_and_mark. (android_sync_edit): Give Emacs 100 ms instead. (android_perform_conversion_query): Skip the active region, not the conversion region. (getSelectedText): Implement properly. (android_update_selection): Expose mark to input methods. (android_reset_conversion): Handle `text-conversion-style'. * src/buffer.c (init_buffer_once, syms_of_buffer): Add buffer local variable `text-conversion-style'. * src/buffer.h (struct buffer, bset_text_conversion_style): New fields. * src/emacs.c (android_emacs_init): Call syms_of_textconv. * src/frame.h (enum text_conversion_operation): Rename TEXTCONV_SET_POINT. * src/lisp.h: Export syms_of_textconv. * src/marker.c (set_marker_internal): Force redisplay when the mark is set and the buffer is visible on builds that use text conversion. Explain why. * src/textconv.c (copy_buffer): Fix copying past gap. (get_mark): New function. (textconv_query): Implement new flag. (sync_overlay): New function. Display conversion text in an overlay. (record_buffer_change, really_commit_text) (really_set_composing_text, really_set_composing_region) (really_delete_surrounding_text, really_set_point) (handle_pending_conversion_events_1, decrement_inside) (handle_pending_conversion_events, textconv_set_point) (get_extracted_text, register_textconv_interface): Various fixes and improvements. * src/textconv.h (struct textconv_interface): Update documentation. * src/window.h (GCALIGNED_STRUCT): New field `prev_mark'. * src/xdisp.c (mark_window_display_accurate_1): Handle prev_mark.
Diffstat (limited to 'src/textconv.c')
-rw-r--r--src/textconv.c315
1 files changed, 289 insertions, 26 deletions
diff --git a/src/textconv.c b/src/textconv.c
index a39748457d3..835d03f3037 100644
--- a/src/textconv.c
+++ b/src/textconv.c
@@ -89,13 +89,27 @@ copy_buffer (ptrdiff_t beg, ptrdiff_t beg_byte,
89 size = end0 - beg0; 89 size = end0 - beg0;
90 memcpy (buffer, BYTE_POS_ADDR (beg0), size); 90 memcpy (buffer, BYTE_POS_ADDR (beg0), size);
91 if (beg1 != -1) 91 if (beg1 != -1)
92 memcpy (buffer, BEG_ADDR + beg1, end1 - beg1); 92 memcpy (buffer + size, BEG_ADDR + beg1, end1 - beg1);
93} 93}
94 94
95 95
96 96
97/* Conversion query. */ 97/* Conversion query. */
98 98
99/* Return the position of the active mark, or -1 if there is no mark
100 or it is not active. */
101
102static ptrdiff_t
103get_mark (void)
104{
105 if (!NILP (BVAR (current_buffer, mark_active))
106 && XMARKER (BVAR (current_buffer, mark))->buffer)
107 return marker_position (BVAR (current_buffer,
108 mark));
109
110 return -1;
111}
112
99/* Perform the text conversion operation specified in QUERY and return 113/* Perform the text conversion operation specified in QUERY and return
100 the results. 114 the results.
101 115
@@ -109,6 +123,9 @@ copy_buffer (ptrdiff_t beg, ptrdiff_t beg_byte,
109 If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move PT past 123 If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move PT past
110 the conversion region in the specified direction if it is inside. 124 the conversion region in the specified direction if it is inside.
111 125
126 If FLAGS & TEXTCONV_SKIP_ACTIVE_REGION, then also move PT past the
127 region if the mark is active.
128
112 Value is 0 if QUERY->operation was not TEXTCONV_SUBSTITUTION 129 Value is 0 if QUERY->operation was not TEXTCONV_SUBSTITUTION
113 or if deleting the text was successful, and 1 otherwise. */ 130 or if deleting the text was successful, and 1 otherwise. */
114 131
@@ -169,6 +186,39 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query,
169 } 186 }
170 } 187 }
171 188
189 /* Likewise for the region if the mark is active. */
190
191 if (flags & TEXTCONV_SKIP_ACTIVE_REGION)
192 {
193 temp = get_mark ();
194
195 if (temp == -1)
196 goto escape;
197
198 start = min (temp, PT);
199 end = max (temp, PT);
200
201 if (pos >= start && pos < end)
202 {
203 switch (query->direction)
204 {
205 case TEXTCONV_FORWARD_CHAR:
206 case TEXTCONV_FORWARD_WORD:
207 case TEXTCONV_CARET_DOWN:
208 case TEXTCONV_NEXT_LINE:
209 case TEXTCONV_LINE_START:
210 pos = end;
211 break;
212
213 default:
214 pos = max (BEGV, start);
215 break;
216 }
217 }
218 }
219
220 escape:
221
172 /* If pos is outside the accessible part of the buffer or if it 222 /* If pos is outside the accessible part of the buffer or if it
173 overflows, move back to point or to the extremes of the 223 overflows, move back to point or to the extremes of the
174 accessible region. */ 224 accessible region. */
@@ -335,6 +385,55 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query,
335 return 0; 385 return 0;
336} 386}
337 387
388/* Update the overlay displaying the conversion area on F after a
389 change to the conversion region. */
390
391static void
392sync_overlay (struct frame *f)
393{
394 if (MARKERP (f->conversion.compose_region_start))
395 {
396 if (NILP (f->conversion.compose_region_overlay))
397 {
398 f->conversion.compose_region_overlay
399 = Fmake_overlay (f->conversion.compose_region_start,
400 f->conversion.compose_region_end, Qnil,
401 Qt, Qnil);
402 Foverlay_put (f->conversion.compose_region_overlay,
403 Qface, Qunderline);
404 }
405
406 Fmove_overlay (f->conversion.compose_region_overlay,
407 f->conversion.compose_region_start,
408 f->conversion.compose_region_end, Qnil);
409 }
410 else if (!NILP (f->conversion.compose_region_overlay))
411 {
412 Fdelete_overlay (f->conversion.compose_region_overlay);
413 f->conversion.compose_region_overlay = Qnil;
414 }
415}
416
417/* Record a change to the current buffer as a result of an
418 asynchronous text conversion operation on F.
419
420 Consult the doc string of `text-conversion-edits' for the meaning
421 of BEG, END, and EPHEMERAL. */
422
423static void
424record_buffer_change (ptrdiff_t beg, ptrdiff_t end,
425 Lisp_Object ephemeral)
426{
427 Lisp_Object buffer;
428
429 XSETBUFFER (buffer, current_buffer);
430
431 Vtext_conversion_edits
432 = Fcons (list4 (buffer, make_fixnum (beg),
433 make_fixnum (end), ephemeral),
434 Vtext_conversion_edits);
435}
436
338/* Reset F's text conversion state. Delete any overlays or 437/* Reset F's text conversion state. Delete any overlays or
339 markers inside. */ 438 markers inside. */
340 439
@@ -438,8 +537,10 @@ really_commit_text (struct frame *f, EMACS_INT position,
438 /* Replace its contents. */ 537 /* Replace its contents. */
439 start = marker_position (f->conversion.compose_region_start); 538 start = marker_position (f->conversion.compose_region_start);
440 end = marker_position (f->conversion.compose_region_end); 539 end = marker_position (f->conversion.compose_region_end);
441 safe_del_range (start, end); 540 del_range (start, end);
541 record_buffer_change (start, start, Qnil);
442 Finsert (1, &text); 542 Finsert (1, &text);
543 record_buffer_change (start, PT, text);
443 544
444 /* Move to a the position specified in POSITION. */ 545 /* Move to a the position specified in POSITION. */
445 546
@@ -493,6 +594,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
493 location. */ 594 location. */
494 wanted = PT; 595 wanted = PT;
495 Finsert (1, &text); 596 Finsert (1, &text);
597 record_buffer_change (wanted, PT, text);
496 598
497 if (position < 0) 599 if (position < 0)
498 { 600 {
@@ -520,6 +622,8 @@ really_commit_text (struct frame *f, EMACS_INT position,
520 } 622 }
521 } 623 }
522 624
625 /* This should deactivate the mark. */
626 call0 (Qdeactivate_mark);
523 unbind_to (count, Qnil); 627 unbind_to (count, Qnil);
524} 628}
525 629
@@ -575,12 +679,11 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
575 679
576 if (!MARKERP (f->conversion.compose_region_start)) 680 if (!MARKERP (f->conversion.compose_region_start))
577 { 681 {
578 f->conversion.compose_region_start = Fmake_marker (); 682 f->conversion.compose_region_start
579 f->conversion.compose_region_end = Fmake_marker (); 683 = build_marker (current_buffer, PT, PT_BYTE);
580 Fset_marker (f->conversion.compose_region_start, 684 f->conversion.compose_region_end
581 Fpoint (), Qnil); 685 = build_marker (current_buffer, PT, PT_BYTE);
582 Fset_marker (f->conversion.compose_region_end, 686
583 Fpoint (), Qnil);
584 Fset_marker_insertion_type (f->conversion.compose_region_end, 687 Fset_marker_insertion_type (f->conversion.compose_region_end,
585 Qt); 688 Qt);
586 689
@@ -595,13 +698,19 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
595 Fwiden (); 698 Fwiden ();
596 start = marker_position (f->conversion.compose_region_start); 699 start = marker_position (f->conversion.compose_region_start);
597 end = marker_position (f->conversion.compose_region_end); 700 end = marker_position (f->conversion.compose_region_end);
598 safe_del_range (start, end); 701 del_range (start, end);
599 set_point (start); 702 set_point (start);
703
704 if (start != end)
705 record_buffer_change (start, start, Qnil);
600 } 706 }
601 707
602 /* Insert the new text. */ 708 /* Insert the new text. */
603 Finsert (1, &text); 709 Finsert (1, &text);
604 710
711 if (start != PT)
712 record_buffer_change (start, PT, Qnil);
713
605 /* Now move point to an appropriate location. */ 714 /* Now move point to an appropriate location. */
606 if (position < 0) 715 if (position < 0)
607 { 716 {
@@ -632,6 +741,12 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
632 741
633 set_point (wanted); 742 set_point (wanted);
634 743
744 /* This should deactivate the mark. */
745 call0 (Qdeactivate_mark);
746
747 /* Move the composition overlay. */
748 sync_overlay (f);
749
635 /* If PT hasn't changed, the conversion region definitely has. 750 /* If PT hasn't changed, the conversion region definitely has.
636 Otherwise, redisplay will update the input method instead. */ 751 Otherwise, redisplay will update the input method instead. */
637 752
@@ -693,18 +808,21 @@ really_set_composing_region (struct frame *f, ptrdiff_t start,
693 make_fixnum (start), Qnil); 808 make_fixnum (start), Qnil);
694 Fset_marker (f->conversion.compose_region_end, 809 Fset_marker (f->conversion.compose_region_end,
695 make_fixnum (end), Qnil); 810 make_fixnum (end), Qnil);
811 sync_overlay (f);
696 812
697 unbind_to (count, Qnil); 813 unbind_to (count, Qnil);
698} 814}
699 815
700/* Delete LEFT and RIGHT chars around point. */ 816/* Delete LEFT and RIGHT chars around point or the active mark,
817 whichever is larger, avoiding the composing region if
818 necessary. */
701 819
702static void 820static void
703really_delete_surrounding_text (struct frame *f, ptrdiff_t left, 821really_delete_surrounding_text (struct frame *f, ptrdiff_t left,
704 ptrdiff_t right) 822 ptrdiff_t right)
705{ 823{
706 specpdl_ref count; 824 specpdl_ref count;
707 ptrdiff_t start, end; 825 ptrdiff_t start, end, a, b, a1, b1, lstart, rstart;
708 826
709 /* If F's old selected window is no longer live, fail. */ 827 /* If F's old selected window is no longer live, fail. */
710 828
@@ -719,21 +837,71 @@ really_delete_surrounding_text (struct frame *f, ptrdiff_t left,
719 redisplay. */ 837 redisplay. */
720 Fselect_window (f->old_selected_window, Qt); 838 Fselect_window (f->old_selected_window, Qt);
721 839
722 start = max (BEGV, PT - left); 840 /* Figure out where to start deleting from. */
723 end = min (ZV, PT + right); 841
842 a = get_mark ();
843
844 if (a != -1 && a != PT)
845 lstart = rstart = max (a, PT);
846 else
847 lstart = rstart = PT;
848
849 /* Avoid the composing text. This behavior is identical to how
850 Android's BaseInputConnection actually implements avoiding the
851 composing span. */
852
853 if (MARKERP (f->conversion.compose_region_start))
854 {
855 a = marker_position (f->conversion.compose_region_start);
856 b = marker_position (f->conversion.compose_region_end);
857
858 a1 = min (a, b);
859 b1 = max (a, b);
860
861 lstart = min (lstart, min (PT, a1));
862 rstart = max (rstart, max (PT, b1));
863 }
864
865 if (lstart == rstart)
866 {
867 start = max (BEGV, lstart - left);
868 end = min (ZV, rstart + right);
869
870 del_range (start, end);
871 record_buffer_change (start, start, Qnil);
872 }
873 else
874 {
875 start = max (BEGV, lstart - left);
876 end = lstart;
877
878 del_range (start, end);
879 record_buffer_change (start, start, Qnil);
880
881 start = rstart;
882 end = min (ZV, rstart + right);
883 del_range (start, end);
884 record_buffer_change (start, start, Qnil);
885 }
886
887 /* if the mark is now equal to start, deactivate it. */
888
889 if (get_mark () == PT)
890 call0 (Qdeactivate_mark);
724 891
725 safe_del_range (start, end);
726 unbind_to (count, Qnil); 892 unbind_to (count, Qnil);
727} 893}
728 894
729/* Set point in F to POSITION. 895/* Set point in F to POSITION. If MARK is not POSITION, activate the
896 mark and set MARK to that as well.
730 897
731 If it has not changed, signal an update through the text input 898 If it has not changed, signal an update through the text input
732 interface, which is necessary for the IME to acknowledge that the 899 interface, which is necessary for the IME to acknowledge that the
733 change has completed. */ 900 change has completed. */
734 901
735static void 902static void
736really_set_point (struct frame *f, ptrdiff_t point) 903really_set_point_and_mark (struct frame *f, ptrdiff_t point,
904 ptrdiff_t mark)
737{ 905{
738 specpdl_ref count; 906 specpdl_ref count;
739 907
@@ -763,6 +931,11 @@ really_set_point (struct frame *f, ptrdiff_t point)
763 /* Set the point. */ 931 /* Set the point. */
764 Fgoto_char (make_fixnum (point)); 932 Fgoto_char (make_fixnum (point));
765 933
934 if (mark == point && BVAR (current_buffer, mark_active))
935 call0 (Qdeactivate_mark);
936 else
937 call1 (Qpush_mark, make_fixnum (mark));
938
766 unbind_to (count, Qnil); 939 unbind_to (count, Qnil);
767} 940}
768 941
@@ -845,8 +1018,9 @@ handle_pending_conversion_events_1 (struct frame *f,
845 XFIXNUM (XCDR (data))); 1018 XFIXNUM (XCDR (data)));
846 break; 1019 break;
847 1020
848 case TEXTCONV_SET_POINT: 1021 case TEXTCONV_SET_POINT_AND_MARK:
849 really_set_point (f, XFIXNUM (data)); 1022 really_set_point_and_mark (f, XFIXNUM (XCAR (data)),
1023 XFIXNUM (XCDR (data)));
850 break; 1024 break;
851 1025
852 case TEXTCONV_DELETE_SURROUNDING_TEXT: 1026 case TEXTCONV_DELETE_SURROUNDING_TEXT:
@@ -858,6 +1032,17 @@ handle_pending_conversion_events_1 (struct frame *f,
858 unbind_to (count, Qnil); 1032 unbind_to (count, Qnil);
859} 1033}
860 1034
1035/* Decrement the variable pointed to by *PTR. */
1036
1037static void
1038decrement_inside (void *ptr)
1039{
1040 int *i;
1041
1042 i = ptr;
1043 (*i)--;
1044}
1045
861/* Process any outstanding text conversion events. 1046/* Process any outstanding text conversion events.
862 This may run Lisp or signal. */ 1047 This may run Lisp or signal. */
863 1048
@@ -868,9 +1053,22 @@ handle_pending_conversion_events (void)
868 Lisp_Object tail, frame; 1053 Lisp_Object tail, frame;
869 struct text_conversion_action *action, *next; 1054 struct text_conversion_action *action, *next;
870 bool handled; 1055 bool handled;
1056 static int inside;
1057 specpdl_ref count;
871 1058
872 handled = false; 1059 handled = false;
873 1060
1061 /* Reset Vtext_conversion_edits. Do not do this if called
1062 reentrantly. */
1063
1064 if (!inside)
1065 Vtext_conversion_edits = Qnil;
1066
1067 inside++;
1068
1069 count = SPECPDL_INDEX ();
1070 record_unwind_protect_ptr (decrement_inside, &inside);
1071
874 FOR_EACH_FRAME (tail, frame) 1072 FOR_EACH_FRAME (tail, frame)
875 { 1073 {
876 f = XFRAME (frame); 1074 f = XFRAME (frame);
@@ -905,6 +1103,8 @@ handle_pending_conversion_events (void)
905 handled = true; 1103 handled = true;
906 } 1104 }
907 } 1105 }
1106
1107 unbind_to (count, Qnil);
908} 1108}
909 1109
910/* Start a ``batch edit'' in F. During a batch edit, point_changed 1110/* Start a ``batch edit'' in F. During a batch edit, point_changed
@@ -1057,13 +1257,13 @@ set_composing_region (struct frame *f, ptrdiff_t start,
1057 input_pending = true; 1257 input_pending = true;
1058} 1258}
1059 1259
1060/* Move point in F's selected buffer to POINT. 1260/* Move point in F's selected buffer to POINT and maybe push MARK.
1061 1261
1062 COUNTER means the same as in `start_batch_edit'. */ 1262 COUNTER means the same as in `start_batch_edit'. */
1063 1263
1064void 1264void
1065textconv_set_point (struct frame *f, ptrdiff_t point, 1265textconv_set_point_and_mark (struct frame *f, ptrdiff_t point,
1066 unsigned long counter) 1266 ptrdiff_t mark, unsigned long counter)
1067{ 1267{
1068 struct text_conversion_action *action, **last; 1268 struct text_conversion_action *action, **last;
1069 1269
@@ -1071,8 +1271,9 @@ textconv_set_point (struct frame *f, ptrdiff_t point,
1071 point = MOST_POSITIVE_FIXNUM; 1271 point = MOST_POSITIVE_FIXNUM;
1072 1272
1073 action = xmalloc (sizeof *action); 1273 action = xmalloc (sizeof *action);
1074 action->operation = TEXTCONV_SET_POINT; 1274 action->operation = TEXTCONV_SET_POINT_AND_MARK;
1075 action->data = make_fixnum (point); 1275 action->data = Fcons (make_fixnum (point),
1276 make_fixnum (mark));
1076 action->next = NULL; 1277 action->next = NULL;
1077 action->counter = counter; 1278 action->counter = counter;
1078 for (last = &f->conversion.actions; *last; last = &(*last)->next) 1279 for (last = &f->conversion.actions; *last; last = &(*last)->next)
@@ -1105,6 +1306,9 @@ delete_surrounding_text (struct frame *f, ptrdiff_t left,
1105/* Return N characters of text around point in F's old selected 1306/* Return N characters of text around point in F's old selected
1106 window. 1307 window.
1107 1308
1309 If N is -1, return the text between point and mark instead, given
1310 that the mark is active.
1311
1108 Set *N to the actual number of characters returned, *START_RETURN 1312 Set *N to the actual number of characters returned, *START_RETURN
1109 to the position of the first character returned, *OFFSET to the 1313 to the position of the first character returned, *OFFSET to the
1110 offset of point within that text, *LENGTH to the actual number of 1314 offset of point within that text, *LENGTH to the actual number of
@@ -1137,13 +1341,38 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
1137 /* Temporarily switch to F's selected window at the time of the last 1341 /* Temporarily switch to F's selected window at the time of the last
1138 redisplay. */ 1342 redisplay. */
1139 Fselect_window (f->old_selected_window, Qt); 1343 Fselect_window (f->old_selected_window, Qt);
1344 buffer = NULL;
1140 1345
1141 /* Figure out the bounds of the text to return. */ 1346 /* Figure out the bounds of the text to return. */
1142 start = PT - n / 2; 1347 if (n != -1)
1143 end = PT + n - n / 2; 1348 {
1349 start = PT - n / 2;
1350 end = PT + n - n / 2;
1351 }
1352 else
1353 {
1354 if (!NILP (BVAR (current_buffer, mark_active))
1355 && XMARKER (BVAR (current_buffer, mark))->buffer)
1356 {
1357 start = marker_position (BVAR (current_buffer, mark));
1358 end = PT;
1359
1360 /* Sort start and end. start_byte is used to hold a
1361 temporary value. */
1362
1363 if (start > end)
1364 {
1365 start_byte = end;
1366 end = start;
1367 start = start_byte;
1368 }
1369 }
1370 else
1371 goto finish;
1372 }
1373
1144 start = max (start, BEGV); 1374 start = max (start, BEGV);
1145 end = min (end, ZV); 1375 end = min (end, ZV);
1146 buffer = NULL;
1147 1376
1148 /* Detect overflow. */ 1377 /* Detect overflow. */
1149 1378
@@ -1218,3 +1447,37 @@ register_textconv_interface (struct textconv_interface *interface)
1218{ 1447{
1219 text_interface = interface; 1448 text_interface = interface;
1220} 1449}
1450
1451
1452
1453void
1454syms_of_textconv (void)
1455{
1456 DEFSYM (Qaction, "action");
1457 DEFSYM (Qtext_conversion, "text-conversion");
1458 DEFSYM (Qpush_mark, "push-mark");
1459 DEFSYM (Qunderline, "underline");
1460
1461 DEFVAR_LISP ("text-conversion-edits", Vtext_conversion_edits,
1462 doc: /* List of buffers that were last edited as a result of text conversion.
1463
1464This list can be used while handling a `text-conversion' event to
1465determine the changes which have taken place.
1466
1467Each element of the list describes a single edit in a buffer, of the
1468form:
1469
1470 (BUFFER BEG END EPHEMERAL)
1471
1472If an insertion or a change occured, then BEG and END are buffer
1473positions denote the bounds of the text that was changed or inserted.
1474If EPHEMERAL is t, then the input method will shortly make more
1475changes to the text, so any actions that would otherwise be taken
1476(such as indenting or automatically filling text) should not take
1477place; otherwise, it is a string describing the text which was
1478inserted.
1479
1480If a deletion occured, then BEG and END are the same, and EPHEMERAL is
1481nil. */);
1482 Vtext_conversion_edits = Qnil;
1483}