aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-15 12:00:50 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-04-15 13:09:12 +0200
commit9b2a3895eedb3c46179b1ed923b0f1214da04c5b (patch)
treee6ef6bdf04d1e1aa46e426bcf50b6fd29ad3c5e7
parentc0943ac451051b734711b0c95731ae7c515dbb31 (diff)
downloadbusybox-w32-9b2a3895eedb3c46179b1ed923b0f1214da04c5b.tar.gz
busybox-w32-9b2a3895eedb3c46179b1ed923b0f1214da04c5b.tar.bz2
busybox-w32-9b2a3895eedb3c46179b1ed923b0f1214da04c5b.zip
vi: correctly record deleted characters
The undo queue didn't record deleted characters properly. For example, insert some text, backspace over a couple of characters then exit insert mode. At this point undo will restore two nulls instead of the deleted characters. The fix is in undo_push(): record the state of the UNDO_USE_SPOS flag and clear it before using 'u_type'. Also, update the comments to reflect the fact that UNDO_QUEUED_FLAG isn't actually used. function old new delta undo_push 443 435 -8 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-8) Total: -8 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 31b5d3e8a..fef328117 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -399,26 +399,31 @@ struct globals {
399#define UNDO_DEL 1 399#define UNDO_DEL 1
400#define UNDO_INS_CHAIN 2 400#define UNDO_INS_CHAIN 2
401#define UNDO_DEL_CHAIN 3 401#define UNDO_DEL_CHAIN 3
402// UNDO_*_QUEUED must be equal to UNDO_xxx ORed with UNDO_QUEUED_FLAG 402# if ENABLE_FEATURE_VI_UNDO_QUEUE
403#define UNDO_QUEUED_FLAG 4
404#define UNDO_INS_QUEUED 4 403#define UNDO_INS_QUEUED 4
405#define UNDO_DEL_QUEUED 5 404#define UNDO_DEL_QUEUED 5
406#define UNDO_USE_SPOS 32 405# endif
407#define UNDO_EMPTY 64 406
408// Pass-through flags for functions that can be undone 407// Pass-through flags for functions that can be undone
409#define NO_UNDO 0 408#define NO_UNDO 0
410#define ALLOW_UNDO 1 409#define ALLOW_UNDO 1
411#define ALLOW_UNDO_CHAIN 2 410#define ALLOW_UNDO_CHAIN 2
412# if ENABLE_FEATURE_VI_UNDO_QUEUE 411# if ENABLE_FEATURE_VI_UNDO_QUEUE
413#define ALLOW_UNDO_QUEUED 3 412#define ALLOW_UNDO_QUEUED 3
414 char undo_queue_state; 413# else
414// If undo queuing disabled, don't invoke the missing queue logic
415#define ALLOW_UNDO_QUEUED ALLOW_UNDO
416# endif
417
418# if ENABLE_FEATURE_VI_UNDO_QUEUE
419#define UNDO_USE_SPOS 32
420#define UNDO_EMPTY 64
421 char undo_queue_state; // One of UNDO_INS, UNDO_DEL, UNDO_EMPTY
415 int undo_q; 422 int undo_q;
416 char *undo_queue_spos; // Start position of queued operation 423 char *undo_queue_spos; // Start position of queued operation
417 char undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX]; 424 char undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX];
418# else
419// If undo queuing disabled, don't invoke the missing queue logic
420#define ALLOW_UNDO_QUEUED 1
421# endif 425# endif
426
422 struct undo_object { 427 struct undo_object {
423 struct undo_object *prev; // Linking back avoids list traversal (LIFO) 428 struct undo_object *prev; // Linking back avoids list traversal (LIFO)
424 int start; // Offset where the data should be restored/deleted 429 int start; // Offset where the data should be restored/deleted
@@ -1445,7 +1450,7 @@ static void yank_status(const char *op, const char *p, int cnt)
1445#endif /* FEATURE_VI_YANKMARK */ 1450#endif /* FEATURE_VI_YANKMARK */
1446 1451
1447#if ENABLE_FEATURE_VI_UNDO 1452#if ENABLE_FEATURE_VI_UNDO
1448static void undo_push(char *, unsigned, unsigned char); 1453static void undo_push(char *, unsigned, int);
1449#endif 1454#endif
1450 1455
1451// open a hole in text[] 1456// open a hole in text[]
@@ -1572,9 +1577,12 @@ static void flush_undo_data(void)
1572 1577
1573// Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com) 1578// Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com)
1574// Add to the undo stack 1579// Add to the undo stack
1575static void undo_push(char *src, unsigned length, uint8_t u_type) 1580static void undo_push(char *src, unsigned length, int u_type)
1576{ 1581{
1577 struct undo_object *undo_entry; 1582 struct undo_object *undo_entry;
1583# if ENABLE_FEATURE_VI_UNDO_QUEUE
1584 int use_spos = u_type & UNDO_USE_SPOS;
1585# endif
1578 1586
1579 // "u_type" values 1587 // "u_type" values
1580 // UNDO_INS: insertion, undo will remove from buffer 1588 // UNDO_INS: insertion, undo will remove from buffer
@@ -1583,8 +1591,8 @@ static void undo_push(char *src, unsigned length, uint8_t u_type)
1583 // The CHAIN operations are for handling multiple operations that the user 1591 // The CHAIN operations are for handling multiple operations that the user
1584 // performs with a single action, i.e. REPLACE mode or find-and-replace commands 1592 // performs with a single action, i.e. REPLACE mode or find-and-replace commands
1585 // UNDO_{INS,DEL}_QUEUED: If queuing feature is enabled, allow use of the queue 1593 // UNDO_{INS,DEL}_QUEUED: If queuing feature is enabled, allow use of the queue
1586 // for the INS/DEL operation. The raw values should be equal to the values of 1594 // for the INS/DEL operation.
1587 // UNDO_{INS,DEL} ORed with UNDO_QUEUED_FLAG 1595 // UNDO_{INS,DEL} ORed with UNDO_USE_SPOS: commit the undo queue
1588 1596
1589# if ENABLE_FEATURE_VI_UNDO_QUEUE 1597# if ENABLE_FEATURE_VI_UNDO_QUEUE
1590 // This undo queuing functionality groups multiple character typing or backspaces 1598 // This undo queuing functionality groups multiple character typing or backspaces
@@ -1637,9 +1645,7 @@ static void undo_push(char *src, unsigned length, uint8_t u_type)
1637 } 1645 }
1638 break; 1646 break;
1639 } 1647 }
1640# else 1648 u_type &= ~UNDO_USE_SPOS;
1641 // If undo queuing is disabled, ignore the queuing flag entirely
1642 u_type = u_type & ~UNDO_QUEUED_FLAG;
1643# endif 1649# endif
1644 1650
1645 // Allocate a new undo object 1651 // Allocate a new undo object
@@ -1656,12 +1662,11 @@ static void undo_push(char *src, unsigned length, uint8_t u_type)
1656 } 1662 }
1657 undo_entry->length = length; 1663 undo_entry->length = length;
1658# if ENABLE_FEATURE_VI_UNDO_QUEUE 1664# if ENABLE_FEATURE_VI_UNDO_QUEUE
1659 if ((u_type & UNDO_USE_SPOS) != 0) { 1665 if (use_spos) {
1660 undo_entry->start = undo_queue_spos - text; // use start position from queue 1666 undo_entry->start = undo_queue_spos - text; // use start position from queue
1661 } else { 1667 } else {
1662 undo_entry->start = src - text; // use offset from start of text buffer 1668 undo_entry->start = src - text; // use offset from start of text buffer
1663 } 1669 }
1664 u_type = (u_type & ~UNDO_USE_SPOS);
1665# else 1670# else
1666 undo_entry->start = src - text; 1671 undo_entry->start = src - text;
1667# endif 1672# endif