diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2014-04-03 01:45:05 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-04-03 01:45:05 +0200 |
commit | 2c51202aece44d0f72b7d496ac94823e10d08d54 (patch) | |
tree | 90f73c49cd485842df40510ea3ba602b17ea6bd2 | |
parent | a8d6f9bee43aba077f7a3a9bcb6ac64e5d877278 (diff) | |
download | busybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.tar.gz busybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.tar.bz2 busybox-w32-2c51202aece44d0f72b7d496ac94823e10d08d54.zip |
vi: undo code shrink
function old new delta
undo_push 414 395 -19
do_cmd 4803 4761 -42
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/vi.c | 83 |
1 files changed, 42 insertions, 41 deletions
diff --git a/editors/vi.c b/editors/vi.c index e38667ad1..71086c901 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2209,7 +2209,8 @@ static void showmatching(char *p) | |||
2209 | // Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com) | 2209 | // Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com) |
2210 | static void undo_push(char *src, unsigned int length, unsigned char u_type) // Add to the undo stack | 2210 | static void undo_push(char *src, unsigned int length, unsigned char u_type) // Add to the undo stack |
2211 | { | 2211 | { |
2212 | struct undo_object *undo_temp; | 2212 | struct undo_object *undo_entry; |
2213 | |||
2213 | // "u_type" values | 2214 | // "u_type" values |
2214 | // UNDO_INS: insertion, undo will remove from buffer | 2215 | // UNDO_INS: insertion, undo will remove from buffer |
2215 | // UNDO_DEL: deleted text, undo will restore to buffer | 2216 | // UNDO_DEL: deleted text, undo will restore to buffer |
@@ -2237,7 +2238,7 @@ static void undo_push(char *src, unsigned int length, unsigned char u_type) // A | |||
2237 | case UNDO_DEL: | 2238 | case UNDO_DEL: |
2238 | undo_queue_spos = src; | 2239 | undo_queue_spos = src; |
2239 | undo_q++; | 2240 | undo_q++; |
2240 | undo_queue[(CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q)] = *src; | 2241 | undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q] = *src; |
2241 | // If queue is full, dump it into an object | 2242 | // If queue is full, dump it into an object |
2242 | if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX) | 2243 | if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX) |
2243 | undo_queue_commit(); | 2244 | undo_queue_commit(); |
@@ -2275,80 +2276,80 @@ static void undo_push(char *src, unsigned int length, unsigned char u_type) // A | |||
2275 | #endif | 2276 | #endif |
2276 | 2277 | ||
2277 | // Allocate a new undo object and use it as the stack tail | 2278 | // Allocate a new undo object and use it as the stack tail |
2278 | undo_temp = undo_stack_tail; | 2279 | undo_entry = xzalloc(sizeof(*undo_entry)); |
2279 | undo_stack_tail = xmalloc(sizeof(struct undo_object)); | 2280 | undo_entry->prev = undo_stack_tail; |
2281 | undo_stack_tail = undo_entry; | ||
2280 | #if ENABLE_FEATURE_VI_UNDO_QUEUE | 2282 | #if ENABLE_FEATURE_VI_UNDO_QUEUE |
2281 | if ((u_type & UNDO_USE_SPOS) != 0) { | 2283 | if ((u_type & UNDO_USE_SPOS) != 0) { |
2282 | undo_stack_tail->start = undo_queue_spos - text; // use start position from queue | 2284 | undo_entry->start = undo_queue_spos - text; // use start position from queue |
2283 | } else { | 2285 | } else { |
2284 | undo_stack_tail->start = src - text; // use offset from start of text buffer | 2286 | undo_entry->start = src - text; // use offset from start of text buffer |
2285 | } | 2287 | } |
2286 | u_type = (u_type & ~UNDO_USE_SPOS); | 2288 | u_type = (u_type & ~UNDO_USE_SPOS); |
2287 | #else | 2289 | #else |
2288 | undo_stack_tail->start = src - text; | 2290 | undo_entry->start = src - text; |
2289 | #endif /* ENABLE_FEATURE_VI_UNDO_QUEUE */ | 2291 | #endif |
2290 | // For UNDO_DEL objects, copy the deleted text somewhere | 2292 | // For UNDO_DEL objects, copy the deleted text somewhere |
2291 | switch (u_type) { | 2293 | undo_entry->u_type = u_type; |
2292 | case UNDO_DEL: | 2294 | if (u_type == UNDO_DEL || u_type == UNDO_DEL_CHAIN) { |
2293 | case UNDO_DEL_CHAIN: | 2295 | if ((src + length) == end) |
2294 | if ((src + length) == end) | 2296 | length--; |
2295 | length--; | 2297 | // If this deletion empties text[], strip the newline. When the buffer becomes |
2296 | // If this deletion empties text[], strip the newline. When the buffer becomes | 2298 | // zero-length, a newline is added back, which requires this to compensate. |
2297 | // zero-length, a newline is added back, which requires this to compensate. | 2299 | undo_entry->undo_text = xmalloc(length); |
2298 | undo_stack_tail->undo_text = xmalloc(length); | 2300 | memcpy(undo_entry->undo_text, src, length); |
2299 | memcpy(undo_stack_tail->undo_text, src, length); | ||
2300 | break; | ||
2301 | } | 2301 | } |
2302 | undo_stack_tail->prev = undo_temp; | 2302 | undo_entry->length = length; |
2303 | undo_stack_tail->length = length; | ||
2304 | undo_stack_tail->u_type = u_type; | ||
2305 | file_modified++; | 2303 | file_modified++; |
2306 | } | 2304 | } |
2307 | 2305 | ||
2308 | static void undo_pop(void) // Undo the last operation | 2306 | static void undo_pop(void) // Undo the last operation |
2309 | { | 2307 | { |
2310 | int repeat = 0; | 2308 | int repeat; |
2311 | char *u_start, *u_end; | 2309 | char *u_start, *u_end; |
2312 | struct undo_object *undo_temp; | 2310 | struct undo_object *undo_entry; |
2313 | 2311 | ||
2314 | // Commit pending undo queue before popping (should be unnecessary) | 2312 | // Commit pending undo queue before popping (should be unnecessary) |
2315 | undo_queue_commit(); | 2313 | undo_queue_commit(); |
2316 | 2314 | ||
2315 | undo_entry = undo_stack_tail; | ||
2317 | // Check for an empty undo stack | 2316 | // Check for an empty undo stack |
2318 | if (undo_stack_tail == NULL) { | 2317 | if (!undo_entry) { |
2319 | status_line("Already at oldest change"); | 2318 | status_line("Already at oldest change"); |
2320 | return; | 2319 | return; |
2321 | } | 2320 | } |
2322 | 2321 | ||
2323 | switch (undo_stack_tail->u_type) { | 2322 | switch (undo_entry->u_type) { |
2324 | case UNDO_DEL: | 2323 | case UNDO_DEL: |
2325 | case UNDO_DEL_CHAIN: | 2324 | case UNDO_DEL_CHAIN: |
2326 | // make hole and put in text that was deleted; deallocate text | 2325 | // make hole and put in text that was deleted; deallocate text |
2327 | u_start = text + undo_stack_tail->start; | 2326 | u_start = text + undo_entry->start; |
2328 | text_hole_make(u_start, undo_stack_tail->length); | 2327 | text_hole_make(u_start, undo_entry->length); |
2329 | memcpy(u_start, undo_stack_tail->undo_text, undo_stack_tail->length); | 2328 | memcpy(u_start, undo_entry->undo_text, undo_entry->length); |
2330 | free(undo_stack_tail->undo_text); | 2329 | free(undo_entry->undo_text); |
2331 | status_line("Undo [%d] %s %d chars at position %d", | 2330 | status_line("Undo [%d] %s %d chars at position %d", |
2332 | file_modified, "restored", | 2331 | file_modified, "restored", |
2333 | undo_stack_tail->length, undo_stack_tail->start); | 2332 | undo_entry->length, undo_entry->start |
2333 | ); | ||
2334 | break; | 2334 | break; |
2335 | case UNDO_INS: | 2335 | case UNDO_INS: |
2336 | case UNDO_INS_CHAIN: | 2336 | case UNDO_INS_CHAIN: |
2337 | // delete what was inserted | 2337 | // delete what was inserted |
2338 | u_start = undo_stack_tail->start + text; | 2338 | u_start = undo_entry->start + text; |
2339 | u_end = u_start - 1 + undo_stack_tail->length; | 2339 | u_end = u_start - 1 + undo_entry->length; |
2340 | text_hole_delete(u_start, u_end, NO_UNDO); | 2340 | text_hole_delete(u_start, u_end, NO_UNDO); |
2341 | status_line("Undo [%d] %s %d chars at position %d", | 2341 | status_line("Undo [%d] %s %d chars at position %d", |
2342 | file_modified, "deleted", | 2342 | file_modified, "deleted", |
2343 | undo_stack_tail->length, undo_stack_tail->start); | 2343 | undo_entry->length, undo_entry->start |
2344 | ); | ||
2344 | break; | 2345 | break; |
2345 | } | 2346 | } |
2346 | // For chained operations, continue popping all the way down the chain. | 2347 | repeat = 0; |
2348 | switch (undo_entry->u_type) { | ||
2347 | // If this is the end of a chain, lower modification count and refresh display | 2349 | // If this is the end of a chain, lower modification count and refresh display |
2348 | switch (undo_stack_tail->u_type) { | ||
2349 | case UNDO_DEL: | 2350 | case UNDO_DEL: |
2350 | case UNDO_INS: | 2351 | case UNDO_INS: |
2351 | dot = (text + undo_stack_tail->start); | 2352 | dot = (text + undo_entry->start); |
2352 | refresh(FALSE); | 2353 | refresh(FALSE); |
2353 | break; | 2354 | break; |
2354 | case UNDO_DEL_CHAIN: | 2355 | case UNDO_DEL_CHAIN: |
@@ -2357,11 +2358,11 @@ static void undo_pop(void) // Undo the last operation | |||
2357 | break; | 2358 | break; |
2358 | } | 2359 | } |
2359 | // Deallocate the undo object we just processed | 2360 | // Deallocate the undo object we just processed |
2360 | undo_temp = undo_stack_tail->prev; | 2361 | undo_stack_tail = undo_entry->prev; |
2361 | free(undo_stack_tail); | 2362 | free(undo_entry); |
2362 | undo_stack_tail = undo_temp; | ||
2363 | file_modified--; | 2363 | file_modified--; |
2364 | if (repeat == 1) { | 2364 | // For chained operations, continue popping all the way down the chain. |
2365 | if (repeat) { | ||
2365 | undo_pop(); // Follow the undo chain if one exists | 2366 | undo_pop(); // Follow the undo chain if one exists |
2366 | } | 2367 | } |
2367 | } | 2368 | } |
@@ -2372,7 +2373,7 @@ static void undo_queue_commit(void) // Flush any queued objects to the undo stac | |||
2372 | // Pushes the queue object onto the undo stack | 2373 | // Pushes the queue object onto the undo stack |
2373 | if (undo_q > 0) { | 2374 | if (undo_q > 0) { |
2374 | // Deleted character undo events grow from the end | 2375 | // Deleted character undo events grow from the end |
2375 | undo_push((undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q), | 2376 | undo_push(undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q, |
2376 | undo_q, | 2377 | undo_q, |
2377 | (undo_queue_state | UNDO_USE_SPOS) | 2378 | (undo_queue_state | UNDO_USE_SPOS) |
2378 | ); | 2379 | ); |