diff options
author | Po Lu <luangruo@yahoo.com> | 2024-04-21 21:51:09 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2024-04-29 12:34:39 +0800 |
commit | 430088c9ccec5fe9be57d267f45acdc87aa3b28e (patch) | |
tree | a953f845c4176e4a18a542c1e321f80ad34ab4af | |
parent | ee2e0031d8cc32bb7837ea97ce07ef3b25463223 (diff) | |
download | emacs-430088c9ccec5fe9be57d267f45acdc87aa3b28e.tar.gz emacs-430088c9ccec5fe9be57d267f45acdc87aa3b28e.tar.bz2 emacs-430088c9ccec5fe9be57d267f45acdc87aa3b28e.zip |
Take fields into account during text conversion
* lisp/cus-edit.el (Custom-mode): Enable text conversion, now
that fields are correctly treated.
* src/alloc.c (mark_frame): Mark f->conversion.field.
* src/androidterm.c (android_update_selection): Adjust
conversion region and selection position by the field start and
end.
* src/editfns.c (find_field): Export function.
* src/frame.c (make_frame): Clear f->conversion.field.
* src/frame.h (struct text_conversion_state) <field>: New field.
* src/lisp.h (find_fields, reset_frame_conversion): Export
functions.
* src/minibuf.c (Fread_from_minibuffer): Reset frame conversion
if Voverriding_text_conversion_style is set.
* src/textconv.c (textconv_query): Narrow to field.
(reset_frame_conversion): New function.
(reset_frame_state): Clear conversion field.
(really_delete_surrounding_text): Narrow to field.
(locate_and_save_position_in_field): New function.
(really_request_point_update, really_set_point_and_mark)
(complete_edit_check, handle_pending_conversion_events_1)
(handle_pending_conversion_events, get_conversion_field)
(set_composing_region, textconv_set_point_and_mark, replace_text)
(get_extracted_text, get_surrounding_text, report_point_change):
Compute, narrow to and offset by the currently active field
whenever point is updated or a command is received.
(syms_of_textconv): Revise doc strings.
* src/textconv.h (get_conversion_field): Export function.
-rw-r--r-- | lisp/cus-edit.el | 1 | ||||
-rw-r--r-- | src/alloc.c | 1 | ||||
-rw-r--r-- | src/androidterm.c | 39 | ||||
-rw-r--r-- | src/editfns.c | 2 | ||||
-rw-r--r-- | src/frame.c | 1 | ||||
-rw-r--r-- | src/frame.h | 4 | ||||
-rw-r--r-- | src/lisp.h | 3 | ||||
-rw-r--r-- | src/minibuf.c | 14 | ||||
-rw-r--r-- | src/textconv.c | 296 | ||||
-rw-r--r-- | src/textconv.h | 1 |
10 files changed, 324 insertions, 38 deletions
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index 8915500a501..1659c285d84 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -5400,6 +5400,7 @@ if that value is non-nil." (setq-local custom--invocation-options nil custom--hidden-state 'hidden) (setq-local revert-buffer-function #'custom--revert-buffer) + (setq-local text-conversion-style 'action) (make-local-variable 'custom-options) (make-local-variable 'custom-local-buffer) (custom--initialize-widget-variables) diff --git a/src/alloc.c b/src/alloc.c index a8dfde56739..47a8e4f4bd2 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -7050,6 +7050,7 @@ mark_frame (struct Lisp_Vector *ptr) mark_object (f->conversion.compose_region_start); mark_object (f->conversion.compose_region_end); mark_object (f->conversion.compose_region_overlay); + mark_object (f->conversion.field); for (tem = f->conversion.actions; tem; tem = tem->next) mark_object (tem->data); diff --git a/src/androidterm.c b/src/androidterm.c index 4549941ee2e..f849f0d9919 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -6265,14 +6265,24 @@ android_update_selection (struct frame *f, struct window *w) jobject extracted; jstring string; bool mark_active; + ptrdiff_t field_start, field_end; + + /* Offset these values by the start offset of the field. */ + get_conversion_field (f, &field_start, &field_end); if (MARKERP (f->conversion.compose_region_start)) { eassert (MARKERP (f->conversion.compose_region_end)); /* Indexing in android starts from 0 instead of 1. */ - start = marker_position (f->conversion.compose_region_start) - 1; - end = marker_position (f->conversion.compose_region_end) - 1; + start = marker_position (f->conversion.compose_region_start); + end = marker_position (f->conversion.compose_region_end); + + /* Offset and detect underflow. */ + start = max (start, field_start) - field_start - 1; + end = min (end, field_end) - field_start - 1; + if (end < 0 || start < 0) + end = start = -1; } else start = -1, end = -1; @@ -6288,24 +6298,27 @@ android_update_selection (struct frame *f, struct window *w) /* Figure out where the point and mark are. If the mark is not active, then point is set to equal mark. */ b = XBUFFER (w->contents); - point = min (w->ephemeral_last_point, + point = min (min (max (w->ephemeral_last_point, + field_start), + field_end) - field_start, TYPE_MAXIMUM (jint)); mark = ((!NILP (BVAR (b, mark_active)) && w->last_mark != -1) - ? min (w->last_mark, TYPE_MAXIMUM (jint)) + ? min (min (max (w->last_mark, field_start), + field_end) - field_start, + TYPE_MAXIMUM (jint)) : point); - /* Send the update. Android doesn't employ a concept of ``point'' - and ``mark''; instead, it only has a selection, where the start - of the selection is less than or equal to the end, and the region - is ``active'' when those two values differ. Also, convert the - indices from 1-based Emacs indices to 0-based Android ones. */ - android_update_ic (FRAME_ANDROID_WINDOW (f), min (point, mark) - 1, - max (point, mark) - 1, start, end); + /* Send the update. Android doesn't employ a concept of "point" and + "mark"; instead, it only has a selection, where the start of the + selection is less than or equal to the end, and the region is + "active" when those two values differ. The indices will have been + converted from 1-based Emacs indices to 0-based Android ones. */ + android_update_ic (FRAME_ANDROID_WINDOW (f), min (point, mark), + max (point, mark), start, end); /* Update the extracted text as well, if the input method has asked - for updates. 1 is - InputConnection.GET_EXTRACTED_TEXT_MONITOR. */ + for updates. 1 is InputConnection.GET_EXTRACTED_TEXT_MONITOR. */ if (FRAME_ANDROID_OUTPUT (f)->extracted_text_flags & 1) { diff --git a/src/editfns.c b/src/editfns.c index 4ccf765bd4b..fbfaaf66644 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -370,7 +370,7 @@ at POSITION. */) Either BEG or END may be 0, in which case the corresponding value is not stored. */ -static void +void find_field (Lisp_Object pos, Lisp_Object merge_at_boundary, Lisp_Object beg_limit, ptrdiff_t *beg, Lisp_Object end_limit, ptrdiff_t *end) diff --git a/src/frame.c b/src/frame.c index ff99b0353af..a671dbaa31d 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1001,6 +1001,7 @@ make_frame (bool mini_p) f->conversion.compose_region_start = Qnil; f->conversion.compose_region_end = Qnil; f->conversion.compose_region_overlay = Qnil; + f->conversion.field = Qnil; f->conversion.batch_edit_count = 0; f->conversion.batch_edit_flags = 0; f->conversion.actions = NULL; diff --git a/src/frame.h b/src/frame.h index e03362361a7..63bcce259af 100644 --- a/src/frame.h +++ b/src/frame.h @@ -126,6 +126,10 @@ struct text_conversion_state /* Overlay representing the composing region. */ Lisp_Object compose_region_overlay; + /* Cons of (START END . WINDOW) holding the field to which text + conversion should be confined, or nil if no such field exists. */ + Lisp_Object field; + /* The number of ongoing ``batch edits'' that are causing point reporting to be delayed. */ int batch_edit_count; diff --git a/src/lisp.h b/src/lisp.h index 526248dd2ba..4487948b007 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4933,6 +4933,8 @@ extern void unmark_main_thread (void); /* Defined in editfns.c. */ extern void insert1 (Lisp_Object); +extern void find_field (Lisp_Object, Lisp_Object, Lisp_Object, + ptrdiff_t *, Lisp_Object, ptrdiff_t *); extern void save_excursion_save (union specbinding *); extern void save_excursion_restore (Lisp_Object, Lisp_Object); extern Lisp_Object save_restriction_save (void); @@ -5496,6 +5498,7 @@ extern char *emacs_root_dir (void); #ifdef HAVE_TEXT_CONVERSION /* Defined in textconv.c. */ extern void reset_frame_state (struct frame *); +extern void reset_frame_conversion (struct frame *); extern void report_selected_window_change (struct frame *); extern void report_point_change (struct frame *, struct window *, struct buffer *); diff --git a/src/minibuf.c b/src/minibuf.c index 51816133fb2..1029fcdb1ba 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1367,6 +1367,20 @@ and some related functions, which use zero-indexing for POSITION. */) if (NILP (histpos)) XSETFASTINT (histpos, 0); +#ifdef HAVE_TEXT_CONVERSION + /* If overriding-text-conversion-style is set, assume that it was + changed prior to this call and force text conversion to be reset, + since redisplay might conclude that the value was retained + unmodified from a previous call to Fread_from_minibuffer as the + selected window will not have changed. */ + if (!EQ (Voverriding_text_conversion_style, Qlambda) + /* Separate minibuffer frames are not material here, since they + will already be selected if the situation that this is meant to + prevent is possible. */ + && FRAME_WINDOW_P (SELECTED_FRAME ())) + reset_frame_conversion (SELECTED_FRAME ()); +#endif /* HAVE_TEXT_CONVERSION */ + val = read_minibuf (keymap, initial_contents, prompt, !NILP (read), histvar, histpos, default_value, diff --git a/src/textconv.c b/src/textconv.c index 9625c884e16..8850f3cc6be 100644 --- a/src/textconv.c +++ b/src/textconv.c @@ -195,6 +195,15 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query, : f->selected_window), Qt); w = XWINDOW (selected_window); + /* Narrow to the field, if any. */ + if (!NILP (f->conversion.field)) + { + record_unwind_protect (save_restriction_restore, + save_restriction_save ()); + Fnarrow_to_region (XCAR (f->conversion.field), + XCAR (XCDR (f->conversion.field))); + } + /* Now find the appropriate text bounds for QUERY. First, move point QUERY->position steps forward or backwards. */ @@ -488,6 +497,17 @@ record_buffer_change (ptrdiff_t beg, ptrdiff_t end, Vtext_conversion_edits); } +/* Reset text conversion state of frame F, and resume text conversion. + Delete any overlays or markers inside. */ + +void +reset_frame_conversion (struct frame *f) +{ + reset_frame_state (f); + if (text_interface && FRAME_WINDOW_P (f) && FRAME_VISIBLE_P (f)) + text_interface->reset (f); +} + /* Reset text conversion state of frame F. Delete any overlays or markers inside. */ @@ -530,6 +550,15 @@ reset_frame_state (struct frame *f) /* Clear batch edit state. */ f->conversion.batch_edit_count = 0; f->conversion.batch_edit_flags = 0; + + /* Clear active field. */ + if (!NILP (f->conversion.field)) + { + Fset_marker (XCAR (f->conversion.field), Qnil, Qnil); + Fset_marker (XCAR (XCDR (f->conversion.field)), Qnil, + Qnil); + } + f->conversion.field = Qnil; } /* Return whether or not there are pending edits from an input method @@ -1012,6 +1041,15 @@ really_delete_surrounding_text (struct frame *f, ptrdiff_t left, redisplay. */ select_window (f->old_selected_window, Qt); + /* Narrow to the field, if any. */ + if (!NILP (f->conversion.field)) + { + record_unwind_protect (save_restriction_restore, + save_restriction_save ()); + Fnarrow_to_region (XCAR (f->conversion.field), + XCAR (XCDR (f->conversion.field))); + } + /* Figure out where to start deleting from. */ a = get_mark (); @@ -1078,6 +1116,115 @@ really_delete_surrounding_text (struct frame *f, ptrdiff_t left, unbind_to (count, Qnil); } +/* Save the confines of the field surrounding point in w into F's text + conversion state. If NOTIFY_COMPOSE, notify the input method of + changes to the composition region if they arise in this process. */ + +static void +locate_and_save_position_in_field (struct frame *f, struct window *w, + bool notify_compose) +{ + Lisp_Object pos, window, c1, c2; + specpdl_ref count; + ptrdiff_t beg, end, cstart, cend, newstart, newend; + + /* Set the current buffer to W's. */ + count = SPECPDL_INDEX (); + record_unwind_protect (restore_selected_window, selected_window); + XSETWINDOW (window, w); + select_window (window, Qt); + + /* Search for a field around the current editing position; this should + also serve to confine text conversion to the visible region. */ + XSETFASTINT (pos, min (max (w->ephemeral_last_point, BEGV), ZV)); + find_field (pos, Qnil, Qnil, &beg, Qnil, &end); + + /* If beg is 1 and end is ZV, disable the active field entirely. */ + if (beg == 1 && end == ZV) + { + f->conversion.field = Qnil; + goto exit; + } + + /* Don't cons if a pair already exists. */ + if (!NILP (f->conversion.field)) + { + c1 = f->conversion.field; + c2 = XCDR (c1); + Fset_marker (XCAR (c1), make_fixed_natnum (beg), Qnil); + Fset_marker (XCAR (c2), make_fixed_natnum (end), Qnil); + XSETCDR (c2, window); + } + else + { + c1 = build_marker (current_buffer, beg, CHAR_TO_BYTE (beg)); + c2 = build_marker (current_buffer, end, CHAR_TO_BYTE (end)); + Fset_marker_insertion_type (c2, Qt); + f->conversion.field = Fcons (c1, Fcons (c2, window)); + } + + /* If the composition region is active and oversteps the active field, + restrict it to the same. */ + + if (!NILP (f->conversion.compose_region_start)) + { + cstart = marker_position (f->conversion.compose_region_start); + cend = marker_position (f->conversion.compose_region_end); + + if (cend < beg || cstart > end) + { + /* Remove the composition region in whole. */ + /* Make the composition region markers point elsewhere. */ + + if (!NILP (f->conversion.compose_region_start)) + { + Fset_marker (f->conversion.compose_region_start, Qnil, Qnil); + Fset_marker (f->conversion.compose_region_end, Qnil, Qnil); + f->conversion.compose_region_start = Qnil; + f->conversion.compose_region_end = Qnil; + } + + /* Delete the composition region overlay. */ + + if (!NILP (f->conversion.compose_region_overlay)) + Fdelete_overlay (f->conversion.compose_region_overlay); + + TEXTCONV_DEBUG ("removing composing region outside active field"); + } + else + { + newstart = max (beg, min (cstart, end)); + newend = max (beg, min (cend, end)); + + if (newstart != cstart || newend != cend) + { + TEXTCONV_DEBUG ("confined composing region to %td, %td", + newstart, newend); + Fset_marker (f->conversion.compose_region_end, + make_fixed_natnum (newstart), Qnil); + Fset_marker (f->conversion.compose_region_end, + make_fixed_natnum (newend), Qnil); + } + else + notify_compose = false; + } + } + else + notify_compose = false; + + if (notify_compose + && text_interface->compose_region_changed) + { + if (f->conversion.batch_edit_count > 0) + f->conversion.batch_edit_flags |= PENDING_COMPOSE_CHANGE; + else + text_interface->compose_region_changed (f); + } + + exit: + unbind_to (count, Qnil); +} + /* Update the interface with frame F's new point and mark. If a batch edit is in progress, schedule the update for when it finishes instead. */ @@ -1085,6 +1232,8 @@ really_delete_surrounding_text (struct frame *f, ptrdiff_t left, static void really_request_point_update (struct frame *f) { + struct window *w; + /* If F's old selected window is no longer live, fail. */ if (!WINDOW_LIVE_P (f->old_selected_window)) @@ -1093,9 +1242,11 @@ really_request_point_update (struct frame *f) if (f->conversion.batch_edit_count > 0) f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE; else if (text_interface && text_interface->point_changed) - text_interface->point_changed (f, - XWINDOW (f->old_selected_window), - current_buffer); + { + w = XWINDOW (f->old_selected_window); + locate_and_save_position_in_field (f, w, false); + text_interface->point_changed (f, w, current_buffer); + } } /* Set point in frame F's selected window to POSITION. If MARK is not @@ -1130,9 +1281,11 @@ really_set_point_and_mark (struct frame *f, ptrdiff_t point, if (f->conversion.batch_edit_count > 0) f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE; else if (text_interface && text_interface->point_changed) - text_interface->point_changed (f, - XWINDOW (f->old_selected_window), - current_buffer); + { + w = XWINDOW (f->old_selected_window); + locate_and_save_position_in_field (f, w, false); + text_interface->point_changed (f, w, current_buffer); + } } else /* Set the point. */ @@ -1331,7 +1484,10 @@ complete_edit_check (void *ptr) if (f->conversion.batch_edit_count > 0) f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE; else - text_interface->point_changed (f, context->w, NULL); + { + locate_and_save_position_in_field (f, context->w, false); + text_interface->point_changed (f, context->w, NULL); + } } } } @@ -1400,7 +1556,10 @@ handle_pending_conversion_events_1 (struct frame *f, break; if (f->conversion.batch_edit_flags & PENDING_POINT_CHANGE) - text_interface->point_changed (f, w, buffer); + { + locate_and_save_position_in_field (f, w, false); + text_interface->point_changed (f, w, buffer); + } if (f->conversion.batch_edit_flags & PENDING_COMPOSE_CHANGE) text_interface->compose_region_changed (f); @@ -1529,7 +1688,10 @@ handle_pending_conversion_events (void) if (f->conversion.batch_edit_count > 0) f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE; else - text_interface->point_changed (f, NULL, NULL); + { + locate_and_save_position_in_field (f, w, false); + text_interface->point_changed (f, NULL, NULL); + } } last_point = w->ephemeral_last_point; @@ -1564,6 +1726,39 @@ handle_pending_conversion_events (void) unbind_to (count, Qnil); } +/* Return the confines of the field to which editing operations on frame + F should be constrained in *BEG and *END. Should no field be active, + set *END to MOST_POSITIVE_FIXNUM. */ + +void +get_conversion_field (struct frame *f, ptrdiff_t *beg, ptrdiff_t *end) +{ + Lisp_Object c1, c2; + struct window *w; + + if (!NILP (f->conversion.field)) + { + c1 = f->conversion.field; + c2 = XCDR (c1); + + if (!EQ (XCDR (c2), f->old_selected_window)) + { + /* Update this outdated field location. */ + w = XWINDOW (f->old_selected_window); + locate_and_save_position_in_field (f, w, true); + get_conversion_field (f, beg, end); + return; + } + + *beg = marker_position (XCAR (c1)); + *end = marker_position (XCAR (c2)); + return; + } + + *beg = 1; + *end = MOST_POSITIVE_FIXNUM; +} + /* Start a ``batch edit'' in frame F. During a batch edit, point_changed will not be called until the batch edit ends. @@ -1694,7 +1889,8 @@ set_composing_text (struct frame *f, Lisp_Object object, } /* Make the region between START and END the currently active - ``composing region'' on frame F. + ``composing region'' on frame F. Which of START and END is the + larger value is not significant. The ``composing region'' is a region of text in the buffer that is about to undergo editing by the input method. */ @@ -1704,14 +1900,22 @@ set_composing_region (struct frame *f, ptrdiff_t start, ptrdiff_t end, unsigned long counter) { struct text_conversion_action *action, **last; + ptrdiff_t field_start, field_end, temp; + + if (start > end) + { + temp = end; + end = start; + start = temp; + } - start = min (start, MOST_POSITIVE_FIXNUM); - end = min (end, MOST_POSITIVE_FIXNUM); + get_conversion_field (f, &field_start, &field_end); + start = min (start + field_start - 1, MOST_POSITIVE_FIXNUM); + end = max (start, min (end + field_start - 1, field_end)); action = xmalloc (sizeof *action); action->operation = TEXTCONV_SET_COMPOSING_REGION; - action->data = Fcons (make_fixnum (start), - make_fixnum (end)); + action->data = Fcons (make_fixnum (start), make_fixnum (end)); action->next = NULL; action->counter = counter; for (last = &f->conversion.actions; *last; last = &(*last)->next) @@ -1730,8 +1934,13 @@ textconv_set_point_and_mark (struct frame *f, ptrdiff_t point, ptrdiff_t mark, unsigned long counter) { struct text_conversion_action *action, **last; + ptrdiff_t field_start, field_end; - point = min (point, MOST_POSITIVE_FIXNUM); + get_conversion_field (f, &field_start, &field_end); + point = min (max (point + field_start - 1, field_start), + field_end); + mark = min (max (mark + field_start - 1, field_start), + field_end); action = xmalloc (sizeof *action); action->operation = TEXTCONV_SET_POINT_AND_MARK; @@ -1809,10 +2018,11 @@ textconv_barrier (struct frame *f, unsigned long counter) input_pending = true; } -/* Remove the composing region. Replace the text between START and - END within F's selected window with TEXT; deactivate the mark if it - is active. Subsequently, set point to POSITION relative to TEXT, - much as `commit_text' would. */ +/* Remove the composing region. Replace the text between START and END + (whose order, as in `set_composing_region', is not significant) + within F's selected window with TEXT; deactivate the mark if it is + active. Subsequently, set point to POSITION relative to TEXT, as + `commit_text' would. */ void replace_text (struct frame *f, ptrdiff_t start, ptrdiff_t end, @@ -1820,6 +2030,18 @@ replace_text (struct frame *f, ptrdiff_t start, ptrdiff_t end, unsigned long counter) { struct text_conversion_action *action, **last; + ptrdiff_t field_start, field_end, temp; + + if (start > end) + { + temp = end; + end = start; + start = temp; + } + + get_conversion_field (f, &field_start, &field_end); + start = min (start + field_start - 1, MOST_POSITIVE_FIXNUM); + end = max (start, min (end + field_start - 1, field_end)); action = xmalloc (sizeof *action); action->operation = TEXTCONV_REPLACE_TEXT; @@ -1858,6 +2080,7 @@ get_extracted_text (struct frame *f, ptrdiff_t n, specpdl_ref count; ptrdiff_t start, end, start_byte, end_byte, mark; char *buffer; + ptrdiff_t field_start, field_end; if (!WINDOW_LIVE_P (f->old_selected_window)) return NULL; @@ -1907,6 +2130,15 @@ get_extracted_text (struct frame *f, ptrdiff_t n, goto finish; } + /* Narrow to the field, if any. */ + if (!NILP (f->conversion.field)) + { + record_unwind_protect (save_restriction_restore, + save_restriction_save ()); + Fnarrow_to_region (XCAR (f->conversion.field), + XCAR (XCDR (f->conversion.field))); + } + start = max (start, BEGV); end = min (end, ZV); @@ -1935,7 +2167,8 @@ get_extracted_text (struct frame *f, ptrdiff_t n, } /* Return the offsets. */ - *start_return = start; + get_conversion_field (f, &field_start, &field_end); + *start_return = max (1, start - field_start + 1); *start_offset = min (mark - start, PT - start); *end_offset = max (mark - start, PT - start); *length = end - start; @@ -1968,6 +2201,7 @@ get_surrounding_text (struct frame *f, ptrdiff_t left, { specpdl_ref count; ptrdiff_t start, end, start_byte, end_byte, mark, temp; + ptrdiff_t field_start, field_end; char *buffer; if (!WINDOW_LIVE_P (f->old_selected_window)) @@ -2012,6 +2246,15 @@ get_surrounding_text (struct frame *f, ptrdiff_t left, || ckd_add (&end, end, right)) goto finish; + /* Narrow to the field, if any. */ + if (!NILP (f->conversion.field)) + { + record_unwind_protect (save_restriction_restore, + save_restriction_save ()); + Fnarrow_to_region (XCAR (f->conversion.field), + XCAR (XCDR (f->conversion.field))); + } + start = max (start, BEGV); end = min (end, ZV); @@ -2038,7 +2281,8 @@ get_surrounding_text (struct frame *f, ptrdiff_t left, /* Return the offsets. Unlike `get_extracted_text', this need not sort mark and point. */ - *offset = start; + get_conversion_field (f, &field_start, &field_end); + *offset = max (1, start - field_start + 1); *start_return = mark - start; *end_return = PT - start; *length = end - start; @@ -2110,7 +2354,10 @@ report_point_change (struct frame *f, struct window *window, if (f->conversion.batch_edit_count > 0) f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE; else - text_interface->point_changed (f, window, buffer); + { + locate_and_save_position_in_field (f, window, false); + text_interface->point_changed (f, window, buffer); + } } /* Temporarily disable text conversion. Must be paired with a @@ -2348,8 +2595,9 @@ as indenting or automatically filling text, should not take place. Otherwise, it is either a string containing text that was inserted, text deleted before point, or nil if text was deleted after point. -The list contents are ordered in the reverse order of editing, i.e. -the latest edit first, so you must iterate through the list in reverse. */); +The list contents are arranged in the reverse of the order of editing, +i.e. latest edit first, so you must iterate through the list in +reverse. */); Vtext_conversion_edits = Qnil; DEFVAR_LISP ("overriding-text-conversion-style", diff --git a/src/textconv.h b/src/textconv.h index 61f13ebcb43..e87ff5cd1f8 100644 --- a/src/textconv.h +++ b/src/textconv.h @@ -155,6 +155,7 @@ extern char *get_surrounding_text (struct frame *, ptrdiff_t, extern bool conversion_disabled_p (void); extern void check_postponed_buffers (void); +extern void get_conversion_field (struct frame *, ptrdiff_t *, ptrdiff_t *); extern void register_textconv_interface (struct textconv_interface *); #endif /* _TEXTCONV_H_ */ |