diff options
Diffstat (limited to 'src/textconv.c')
| -rw-r--r-- | src/textconv.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/src/textconv.c b/src/textconv.c index d8166bcfd03..9003816e191 100644 --- a/src/textconv.c +++ b/src/textconv.c | |||
| @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 36 | #include "buffer.h" | 36 | #include "buffer.h" |
| 37 | #include "syntax.h" | 37 | #include "syntax.h" |
| 38 | #include "blockinput.h" | 38 | #include "blockinput.h" |
| 39 | #include "keyboard.h" | ||
| 39 | 40 | ||
| 40 | 41 | ||
| 41 | 42 | ||
| @@ -522,7 +523,11 @@ detect_conversion_events (void) | |||
| 522 | 523 | ||
| 523 | FOR_EACH_FRAME (tail, frame) | 524 | FOR_EACH_FRAME (tail, frame) |
| 524 | { | 525 | { |
| 525 | if (XFRAME (frame)->conversion.actions) | 526 | /* See if there's a pending edit on this frame. */ |
| 527 | if (XFRAME (frame)->conversion.actions | ||
| 528 | && ((XFRAME (frame)->conversion.actions->operation | ||
| 529 | != TEXTCONV_BARRIER) | ||
| 530 | || (kbd_fetch_ptr == kbd_store_ptr))) | ||
| 526 | return true; | 531 | return true; |
| 527 | } | 532 | } |
| 528 | 533 | ||
| @@ -740,7 +745,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position, | |||
| 740 | Fset_marker_insertion_type (f->conversion.compose_region_end, | 745 | Fset_marker_insertion_type (f->conversion.compose_region_end, |
| 741 | Qt); | 746 | Qt); |
| 742 | 747 | ||
| 743 | start = position; | 748 | start = PT; |
| 744 | } | 749 | } |
| 745 | else | 750 | else |
| 746 | { | 751 | { |
| @@ -762,7 +767,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position, | |||
| 762 | record_buffer_change (start, PT, Qnil); | 767 | record_buffer_change (start, PT, Qnil); |
| 763 | 768 | ||
| 764 | /* Now move point to an appropriate location. */ | 769 | /* Now move point to an appropriate location. */ |
| 765 | if (position < 0) | 770 | if (position <= 0) |
| 766 | { | 771 | { |
| 767 | wanted = start; | 772 | wanted = start; |
| 768 | 773 | ||
| @@ -1198,6 +1203,19 @@ handle_pending_conversion_events_1 (struct frame *f, | |||
| 1198 | case TEXTCONV_REQUEST_POINT_UPDATE: | 1203 | case TEXTCONV_REQUEST_POINT_UPDATE: |
| 1199 | really_request_point_update (f); | 1204 | really_request_point_update (f); |
| 1200 | break; | 1205 | break; |
| 1206 | |||
| 1207 | case TEXTCONV_BARRIER: | ||
| 1208 | if (kbd_fetch_ptr != kbd_store_ptr) | ||
| 1209 | emacs_abort (); | ||
| 1210 | |||
| 1211 | /* Once a barrier is hit, synchronize F's selected window's | ||
| 1212 | `ephemeral_last_point' with its current point. The reason | ||
| 1213 | for this is because otherwise a previous keyboard event may | ||
| 1214 | have taken place without redisplay happening in between. */ | ||
| 1215 | |||
| 1216 | if (w) | ||
| 1217 | w->ephemeral_last_point = window_point (w); | ||
| 1218 | break; | ||
| 1201 | } | 1219 | } |
| 1202 | 1220 | ||
| 1203 | /* Signal success. */ | 1221 | /* Signal success. */ |
| @@ -1231,7 +1249,7 @@ handle_pending_conversion_events (void) | |||
| 1231 | static int inside; | 1249 | static int inside; |
| 1232 | specpdl_ref count; | 1250 | specpdl_ref count; |
| 1233 | ptrdiff_t last_point; | 1251 | ptrdiff_t last_point; |
| 1234 | struct window *w; | 1252 | struct window *w, *w1; |
| 1235 | 1253 | ||
| 1236 | handled = false; | 1254 | handled = false; |
| 1237 | 1255 | ||
| @@ -1242,8 +1260,6 @@ handle_pending_conversion_events (void) | |||
| 1242 | Vtext_conversion_edits = Qnil; | 1260 | Vtext_conversion_edits = Qnil; |
| 1243 | 1261 | ||
| 1244 | inside++; | 1262 | inside++; |
| 1245 | last_point = -1; | ||
| 1246 | w = NULL; | ||
| 1247 | 1263 | ||
| 1248 | count = SPECPDL_INDEX (); | 1264 | count = SPECPDL_INDEX (); |
| 1249 | record_unwind_protect_ptr (decrement_inside, &inside); | 1265 | record_unwind_protect_ptr (decrement_inside, &inside); |
| @@ -1251,6 +1267,8 @@ handle_pending_conversion_events (void) | |||
| 1251 | FOR_EACH_FRAME (tail, frame) | 1267 | FOR_EACH_FRAME (tail, frame) |
| 1252 | { | 1268 | { |
| 1253 | f = XFRAME (frame); | 1269 | f = XFRAME (frame); |
| 1270 | last_point = -1; | ||
| 1271 | w = NULL; | ||
| 1254 | 1272 | ||
| 1255 | /* Test if F has any outstanding conversion events. Then | 1273 | /* Test if F has any outstanding conversion events. Then |
| 1256 | process them in bottom to up order. */ | 1274 | process them in bottom to up order. */ |
| @@ -1283,6 +1301,13 @@ handle_pending_conversion_events (void) | |||
| 1283 | if (!action) | 1301 | if (!action) |
| 1284 | break; | 1302 | break; |
| 1285 | 1303 | ||
| 1304 | /* If action is a barrier event and the keyboard buffer is | ||
| 1305 | not yet empty, break out of the loop. */ | ||
| 1306 | |||
| 1307 | if (action->operation == TEXTCONV_BARRIER | ||
| 1308 | && kbd_store_ptr != kbd_fetch_ptr) | ||
| 1309 | break; | ||
| 1310 | |||
| 1286 | /* Unlink this action. */ | 1311 | /* Unlink this action. */ |
| 1287 | next = action->next; | 1312 | next = action->next; |
| 1288 | f->conversion.actions = next; | 1313 | f->conversion.actions = next; |
| @@ -1515,6 +1540,29 @@ request_point_update (struct frame *f, unsigned long counter) | |||
| 1515 | input_pending = true; | 1540 | input_pending = true; |
| 1516 | } | 1541 | } |
| 1517 | 1542 | ||
| 1543 | /* Request that text conversion on F pause until the keyboard buffer | ||
| 1544 | becomes empty. | ||
| 1545 | |||
| 1546 | Use this function to ensure that edits associated with a keyboard | ||
| 1547 | event complete before the text conversion edits after the barrier | ||
| 1548 | take place. */ | ||
| 1549 | |||
| 1550 | void | ||
| 1551 | textconv_barrier (struct frame *f, unsigned long counter) | ||
| 1552 | { | ||
| 1553 | struct text_conversion_action *action, **last; | ||
| 1554 | |||
| 1555 | action = xmalloc (sizeof *action); | ||
| 1556 | action->operation = TEXTCONV_BARRIER; | ||
| 1557 | action->data = Qnil; | ||
| 1558 | action->next = NULL; | ||
| 1559 | action->counter = counter; | ||
| 1560 | for (last = &f->conversion.actions; *last; last = &(*last)->next) | ||
| 1561 | ;; | ||
| 1562 | *last = action; | ||
| 1563 | input_pending = true; | ||
| 1564 | } | ||
| 1565 | |||
| 1518 | /* Return N characters of text around point in F's old selected | 1566 | /* Return N characters of text around point in F's old selected |
| 1519 | window. | 1567 | window. |
| 1520 | 1568 | ||