Optionally allow point to enter composed character sequences
This changeset is based on code originally posted by Kenichi Handa <handa@gnu.org> as part of discussing bug#20140, with a few adjustments and changes, mainly to support R2L text and provide a user option to control the feature. * src/xdisp.c (compute_stop_pos, next_element_from_buffer) (composition_reseat_it): Don't allow auto-composing characters past point when 'composition-break-at-point' is non-nil. (syms_of_xdisp) <composition-break-at-point>: New boolean variable. (redisplay_internal, redisplay_window): Disable "just move the cursor" optimizations when 'composition-break-at-point' is non-nil. * src/keyboard.c (command_loop_1): Force redisplay when 'composition-break-at-point' is non-nil. * lisp/cus-start.el (standard): Provide customization form for 'composition-break-at-point'. * etc/NEWS: Announce the new feature.
This commit is contained in:
parent
09fecae877
commit
b5997c0f10
5 changed files with 79 additions and 19 deletions
11
etc/NEWS
11
etc/NEWS
|
@ -476,6 +476,17 @@ The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event'
|
|||
been added to better support systems where two kinds of wheel events can be
|
||||
received.
|
||||
|
||||
** Editing complex text layout (CTL) scripts
|
||||
|
||||
*** The <Delete> function key now allows deleting the entire composed sequence.
|
||||
For the details, see the item about the 'delete-forward-char' command
|
||||
above.
|
||||
|
||||
*** New user option 'composition-break-at-point'.
|
||||
Setting it to a non-nil value temporarily disables automatic
|
||||
composition of character sequences at point, and thus makes it easier
|
||||
to edit such sequences by allowing point to "enter" the sequence.
|
||||
|
||||
|
||||
* Changes in Specialized Modes and Packages in Emacs 29.1
|
||||
|
||||
|
|
|
@ -811,6 +811,7 @@ since it could result in memory overflow and make Emacs crash."
|
|||
character)
|
||||
"27.1"
|
||||
:safe (lambda (value) (or (characterp value) (null value))))
|
||||
(composition-break-at-point display boolean "29.1")
|
||||
;; xfaces.c
|
||||
(scalable-fonts-allowed
|
||||
display (choice (const :tag "Don't allow scalable fonts" nil)
|
||||
|
|
|
@ -1292,6 +1292,16 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
|
|||
if (cmp_it->lookback > 0)
|
||||
{
|
||||
cpos = charpos - cmp_it->lookback;
|
||||
/* Reject the composition if it starts before ENDPOS,
|
||||
which here can only happen if
|
||||
composition-break-at-point is non-nil and point is
|
||||
inside the composition. */
|
||||
if (cpos < endpos)
|
||||
{
|
||||
eassert (composition_break_at_point);
|
||||
eassert (endpos == PT);
|
||||
goto no_composition;
|
||||
}
|
||||
if (STRINGP (string))
|
||||
bpos = string_char_to_byte (string, cpos);
|
||||
else
|
||||
|
|
|
@ -1603,23 +1603,33 @@ command_loop_1 (void)
|
|||
|
||||
if (current_buffer == prev_buffer
|
||||
&& XBUFFER (XWINDOW (selected_window)->contents) == current_buffer
|
||||
&& last_point_position != PT
|
||||
&& NILP (Vdisable_point_adjustment)
|
||||
&& NILP (Vglobal_disable_point_adjustment))
|
||||
&& last_point_position != PT)
|
||||
{
|
||||
if (last_point_position > BEGV
|
||||
&& last_point_position < ZV
|
||||
&& (composition_adjust_point (last_point_position,
|
||||
last_point_position)
|
||||
!= last_point_position))
|
||||
/* The last point was temporarily set within a grapheme
|
||||
cluster to prevent automatic composition. To recover
|
||||
the automatic composition, we must update the
|
||||
display. */
|
||||
windows_or_buffers_changed = 21;
|
||||
if (!already_adjusted)
|
||||
adjust_point_for_property (last_point_position,
|
||||
MODIFF != prev_modiff);
|
||||
if (NILP (Vdisable_point_adjustment)
|
||||
&& NILP (Vglobal_disable_point_adjustment)
|
||||
&& !composition_break_at_point)
|
||||
{
|
||||
if (last_point_position > BEGV
|
||||
&& last_point_position < ZV
|
||||
&& (composition_adjust_point (last_point_position,
|
||||
last_point_position)
|
||||
!= last_point_position))
|
||||
/* The last point was temporarily set within a grapheme
|
||||
cluster to prevent automatic composition. To recover
|
||||
the automatic composition, we must update the
|
||||
display. */
|
||||
windows_or_buffers_changed = 21;
|
||||
if (!already_adjusted)
|
||||
adjust_point_for_property (last_point_position,
|
||||
MODIFF != prev_modiff);
|
||||
}
|
||||
else if (PT > BEGV && PT < ZV
|
||||
&& (composition_adjust_point (last_point_position, PT)
|
||||
!= PT))
|
||||
/* Now point is within a grapheme cluster. We must update
|
||||
the display so that this cluster is de-composed on the
|
||||
screen and the cursor is correctly placed at point. */
|
||||
windows_or_buffers_changed = 39;
|
||||
}
|
||||
|
||||
/* Install chars successfully executed in kbd macro. */
|
||||
|
|
34
src/xdisp.c
34
src/xdisp.c
|
@ -3984,6 +3984,12 @@ compute_stop_pos (struct it *it)
|
|||
pos = next_overlay_change (charpos);
|
||||
if (pos < it->stop_charpos)
|
||||
it->stop_charpos = pos;
|
||||
/* If we are breaking compositions at point, stop at point. */
|
||||
if (!NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
&& !NILP (Vauto_composition_mode)
|
||||
&& composition_break_at_point
|
||||
&& charpos < PT && PT < it->stop_charpos)
|
||||
it->stop_charpos = PT;
|
||||
|
||||
/* Set up variables for computing the stop position from text
|
||||
property changes. */
|
||||
|
@ -3995,7 +4001,8 @@ compute_stop_pos (struct it *it)
|
|||
chunks. We play safe here by assuming that only SPC, TAB,
|
||||
FF, and NL cannot be in some composition; in particular, most
|
||||
ASCII punctuation characters could be composed into ligatures. */
|
||||
if (!NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
if (!composition_break_at_point
|
||||
&& !NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
&& !NILP (Vauto_composition_mode))
|
||||
{
|
||||
ptrdiff_t endpos = charpos + 10 * TEXT_PROP_DISTANCE_LIMIT;
|
||||
|
@ -9186,7 +9193,19 @@ next_element_from_buffer (struct it *it)
|
|||
&& IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
|
||||
run_redisplay_end_trigger_hook (it);
|
||||
|
||||
stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
|
||||
if (composition_break_at_point
|
||||
&& !NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
&& !NILP (Vauto_composition_mode))
|
||||
{
|
||||
/* Limit search for composable characters to point's position. */
|
||||
if (it->bidi_it.scan_dir < 0)
|
||||
stop = (PT <= IT_CHARPOS (*it)) ? PT : -1;
|
||||
else
|
||||
stop = (IT_CHARPOS (*it) < PT
|
||||
&& PT < it->end_charpos) ? PT : it->end_charpos;
|
||||
}
|
||||
else
|
||||
stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
|
||||
if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
|
||||
stop)
|
||||
&& next_element_from_composition (it))
|
||||
|
@ -16390,7 +16409,8 @@ redisplay_internal (void)
|
|||
/* If highlighting the region, or if the cursor is in the echo area,
|
||||
then we can't just move the cursor. */
|
||||
else if (NILP (Vshow_trailing_whitespace)
|
||||
&& !cursor_in_echo_area)
|
||||
&& !cursor_in_echo_area
|
||||
&& !composition_break_at_point)
|
||||
{
|
||||
struct it it;
|
||||
struct glyph_row *row;
|
||||
|
@ -18928,6 +18948,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
&& !current_buffer->clip_changed
|
||||
&& !current_buffer->prevent_redisplay_optimizations_p
|
||||
&& !window_outdated (w)
|
||||
&& !composition_break_at_point
|
||||
&& !hscrolling_current_line_p (w));
|
||||
|
||||
beg_unchanged = BEG_UNCHANGED;
|
||||
|
@ -36527,6 +36548,13 @@ Otherwise, use custom-tailored code after resizing minibuffer windows to try
|
|||
and display the most important part of the minibuffer. */);
|
||||
/* See bug#43519 for some discussion around this. */
|
||||
redisplay_adhoc_scroll_in_resize_mini_windows = true;
|
||||
|
||||
DEFVAR_BOOL ("composition-break-at-point",
|
||||
composition_break_at_point,
|
||||
doc: /* If non-nil, prevent auto-composition of characters around point.
|
||||
This makes it easier to edit character sequences that are
|
||||
composed on display. */);
|
||||
composition_break_at_point = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue