mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
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.
This commit is contained in:
parent
ee2e0031d8
commit
430088c9cc
10 changed files with 324 additions and 38 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
288
src/textconv.c
288
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,9 +1484,12 @@ complete_edit_check (void *ptr)
|
|||
if (f->conversion.batch_edit_count > 0)
|
||||
f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE;
|
||||
else
|
||||
{
|
||||
locate_and_save_position_in_field (f, context->w, false);
|
||||
text_interface->point_changed (f, context->w, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process and free the text conversion ACTION. F must be the frame
|
||||
|
|
@ -1400,7 +1556,10 @@ handle_pending_conversion_events_1 (struct frame *f,
|
|||
break;
|
||||
|
||||
if (f->conversion.batch_edit_flags & PENDING_POINT_CHANGE)
|
||||
{
|
||||
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,8 +1688,11 @@ handle_pending_conversion_events (void)
|
|||
if (f->conversion.batch_edit_count > 0)
|
||||
f->conversion.batch_edit_flags |= PENDING_POINT_CHANGE;
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
start = min (start, MOST_POSITIVE_FIXNUM);
|
||||
end = min (end, MOST_POSITIVE_FIXNUM);
|
||||
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_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
|
||||
{
|
||||
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",
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue