- Timestamp:
- Jul 11, 2009, 1:14:34 PM (15 years ago)
- Branches:
- master, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- 7d25006
- Parents:
- 98f1e69
- git-author:
- Karl Ramm <kcr@1ts.org> (06/10/09 03:29:20)
- git-committer:
- Nelson Elhage <nelhage@mit.edu> (07/11/09 13:14:34)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
editwin.c
r98f1e69 r5b5f3e6 39 39 static int owl_editwin_limit_maxcols(int v, int maxv); 40 40 static int owl_editwin_check_dotsend(owl_editwin *e); 41 static void _owl_editwin_process_char(owl_editwin *e, gunichar j);42 41 static int owl_editwin_is_char_in(owl_editwin *e, char *set); 43 static int owl_editwin_is_char_in(owl_editwin *e, char *set);44 static int owl_editwin_linewrap_word(owl_editwin *e);45 42 static gunichar owl_editwin_get_char_at_point(owl_editwin *e); 46 47 static void _owl_editwin_addspace(owl_editwin *e); 48 static void owl_editwin_overwrite_char(owl_editwin *e, gunichar c); 49 static void owl_editwin_insert_char(owl_editwin *e, gunichar c); 50 static void owl_editwin_overwrite_string(owl_editwin *e, char *string); 51 52 #define INCR 5000 43 static void owl_editwin_replace(owl_editwin *e, int count, char *s); 44 static int oe_count_glyphs(char *s); 45 46 #define INCR 4096 53 47 54 48 #define WHITESPACE " \n\t" … … 57 51 { 58 52 return owl_malloc(sizeof(owl_editwin)); 53 } 54 55 static int oe_count_glyphs(char *s) 56 { 57 int count = 0; 58 char *p; 59 60 for(p = s; *p != 0; p = g_utf8_find_next_char(p, NULL)) 61 if (!g_unichar_ismark(g_utf8_get_char(p))) 62 count++; 63 64 return count; 59 65 } 60 66 … … 192 198 { 193 199 oe_set_index(e, 0); 194 owl_editwin_overwrite_string(e, text); 195 owl_editwin_overwrite_char(e, '\0'); 196 e->lock=strlen(text); 200 e->lock = 0; 201 owl_editwin_replace(e, e->bufflen, text); 202 e->buff[e->bufflen] = 0; 203 e->lock=e->bufflen; 197 204 oe_set_index(e, e->lock); 198 205 owl_editwin_redisplay(e, 0); … … 206 213 void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h) 207 214 { 208 char *ptr;209 210 215 e->hist = h; 211 216 … … 218 223 219 224 /* nuke everything after the first line */ 220 if (e->bufflen > 0) { 221 ptr=strchr(e->buff, '\n')-1; 222 if (ptr) { 223 e->bufflen=ptr - e->buff; 224 e->buff[e->bufflen]='\0'; 225 oe_set_index(e, 0); 226 } 227 } 225 owl_editwin_move_to_top(e); 226 owl_editwin_move_to_end_of_line(e); 227 owl_editwin_replace(e, oe_count_glyphs(e->buff + e->index), ""); 228 228 } 229 229 } … … 248 248 249 249 if (lock > 0) { 250 locktext =owl_malloc(e->lock+20);251 strncpy(locktext, e->buff, e->lock);252 locktext[ e->lock]='\0';250 locktext = owl_malloc(lock+1); 251 strncpy(locktext, e->buff, lock); 252 locktext[lock] = 0; 253 253 } 254 254 … … 266 266 } 267 267 268 if (locktext) owl_free(locktext); 268 if (locktext) 269 owl_free(locktext); 269 270 270 271 oe_set_index(e, lock); 271 }272 273 /* malloc more space for the buffer */274 static void _owl_editwin_addspace(owl_editwin *e)275 {276 e->buff=owl_realloc(e->buff, e->allocated+INCR);277 if (!e->buff) {278 /* error *//*XXXXXXXXXXXXXXXX*/279 return;280 }281 e->allocated+=INCR;282 272 } 283 273 … … 449 439 } 450 440 451 /* Remove n bytes at cursor. */ 452 void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/ 453 { 454 int i = e->index + n; 455 for (; i < e->bufflen; i++) { 456 e->buff[i-n] = e->buff[i]; 457 } 458 459 e->bufflen -= n; 460 e->buff[e->bufflen] = '\0'; 461 } 462 463 /* Insert n bytes at cursor.*/ 464 void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/ 465 { 466 int i; 467 468 if ((e->bufflen + n) > (e->allocated - 5)) { 469 _owl_editwin_addspace(e); 470 } 471 472 if(e->index != e->bufflen) { 473 for (i = e->bufflen + n - 1; i > e->index; i--) { 474 e->buff[i] = e->buff[i - n]; 475 } 476 } 477 478 e->bufflen += n; 479 e->buff[e->bufflen] = '\0'; 480 481 } 482 483 441 static void owl_editwin_replace(owl_editwin *e, int replace, char *s) 442 { /* replace count characters at the point with s */ 443 int start, end, i, free, need, size; 444 char *p; 445 446 if (!g_utf8_validate(s, -1, NULL)) { 447 owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string."); 448 return; 449 } 450 451 start = e->index; 452 for (i = 0, p = e->buff + start; i < replace && p != NULL; i++) 453 p = oe_next_point(e, p); 454 if (p != NULL) 455 end = p - e->buff; 456 else 457 end = e->bufflen; 458 459 free = e->allocated - e->bufflen + end - start; 460 461 need = strlen(s) - free; 462 if (need > 0) { 463 size = e->allocated + need + INCR - (need % INCR); 464 p = realloc(e->buff, size); 465 if (p == NULL) { 466 /* XXX signal impending doom somehow and don't do anything */ 467 return; 468 } 469 e->buff = p; 470 e->allocated = size; 471 } 472 473 memmove(e->buff + start + strlen(s), e->buff + end, e->bufflen + 1 - end); 474 memcpy(e->buff + start, s, strlen(s)); 475 e->bufflen += start - end + strlen(s); 476 e->index += strlen(s); 477 } 478 479 #if 0 /*XXX*/ 484 480 /* linewrap the word just before the cursor. 485 481 * returns 0 on success 486 482 * returns -1 if we could not wrap. 487 483 */ 488 static int owl_editwin_linewrap_word(owl_editwin *e)484 static int _owl_editwin_linewrap_word(owl_editwin *e) 489 485 { 490 486 int i; … … 517 513 return -1; 518 514 } 519 520 /* insert a character at the current point (shift later521 * characters over)522 */523 static void owl_editwin_insert_char(owl_editwin *e, gunichar c)524 {525 int i, ret, len;526 char tmp[6];527 memset(tmp, '\0', 6);528 529 /* \r is \n */530 if (c == '\r') {531 c = '\n';532 }533 534 if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {535 /* perhaps later this will change some state that allows the string536 to be read */537 return;538 }539 540 g_unichar_to_utf8(c, tmp);541 len = strlen(tmp);542 543 /* make sure there is enough memory for the new text */544 if ((e->bufflen + len) > (e->allocated - 5)) {545 _owl_editwin_addspace(e);546 }547 548 /* If we're going to insert at the last column do word wrapping, unless it's a \n */549 #if 0 /* XXX */550 if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {551 ret = _owl_editwin_linewrap_word(e);552 if (ret == -1) {553 /* we couldn't wrap, insert a hard newline instead */554 owl_editwin_insert_char(e, '\n');555 }556 }557 515 #endif 558 559 /* shift all the other characters right */560 _owl_editwin_insert_bytes(e, len);561 562 /* insert the new character */563 for(i = 0; i < len; i++) {564 e->buff[e->index + i] = tmp[i];565 }566 567 /* advance the cursor */568 oe_set_index(e, e->index + len);569 }570 571 /* overwrite the character at the current point with 'c' */572 static void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)573 {574 int oldlen, newlen, i;575 char tmp[6], *t;576 memset(tmp, '\0', 6);577 578 /* \r is \n */579 if (c == '\r') {580 c = '\n';581 }582 583 if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {584 /* perhaps later this will change some state that allows the string585 to be read */586 return;587 }588 589 g_unichar_to_utf8(c, tmp);590 newlen = strlen(tmp);591 592 t = g_utf8_find_next_char(e->buff + e->index, NULL);593 oldlen = (t ? (t - (e->buff + e->index)) : 0);594 595 /* only if we are at the end of the buffer do we create new space here */596 if (e->index == e->bufflen) {597 if ((e->bufflen+newlen) > (e->allocated-5)) {598 _owl_editwin_addspace(e);599 }600 }601 /* if not at the end of the buffer, adjust based in char size difference. */602 else if (oldlen > newlen) {603 _owl_editwin_remove_bytes(e, oldlen-newlen);604 }605 else /* oldlen < newlen */ {606 _owl_editwin_insert_bytes(e, newlen-oldlen);607 }608 /* Overwrite the old char*/609 for (i = 0; i < newlen; i++) {610 e->buff[e->index + i] = tmp[i];611 }612 613 /* housekeeping */614 if (e->index == e->bufflen) {615 e->bufflen += newlen;616 e->buff[e->bufflen] = '\0';617 }618 619 /* advance the cursor */620 oe_set_index(e, e->index + newlen);621 }622 516 623 517 /* delete the character at the current point, following chars … … 626 520 void owl_editwin_delete_char(owl_editwin *e) 627 521 { 628 char *p1, *p2; 629 gunichar c; 630 631 if (e->bufflen == 0) return; 632 633 if (e->index == e->bufflen) return; 634 635 p1 = e->buff + e->index; 636 p2 = g_utf8_next_char(p1); 637 c = g_utf8_get_char(p2); 638 while (g_unichar_ismark(c)) { 639 p2 = g_utf8_next_char(p2); 640 c = g_utf8_get_char(p2); 641 } 642 _owl_editwin_remove_bytes(e, p2-p1); 522 owl_editwin_replace(e, 1, ""); 643 523 } 644 524 … … 650 530 void owl_editwin_transpose_chars(owl_editwin *e) 651 531 { 652 char * p1, *p2, *p3, *tmp;532 char *middle, *end, *start, *tmp; 653 533 654 534 if (e->bufflen == 0) return; 655 535 656 if (e->index == e->bufflen) { 657 /* point is after last character */ 658 oe_set_index(e, e->index - 1); 659 } 660 661 if (e->index - 1 < e->lock) { 662 /* point is at beginning of buffer, do nothing */ 536 if (e->index == e->bufflen) 537 owl_editwin_point_move(e, -1); /* point is after last character */ 538 539 if (owl_editwin_at_beginning_of_buffer(e)) 540 return; /* point is at beginning of buffer, do nothing */ 541 542 /* Transpose two utf-8 unicode glyphs. */ 543 middle = e->buff + e->index; 544 545 end = oe_next_point(e, middle); 546 if (end == NULL) 663 547 return; 664 } 665 666 /* Transpose two utf-8 unicode glyphs. */ 667 p1 = e->buff + e->index; 668 669 p2 = oe_next_point(e, p1); /* XXX make sure we can't transpose past the end 670 of the buffer */ 671 if (p2 == NULL) 548 549 start = oe_prev_point(e, middle); 550 if (start == NULL) 672 551 return; 673 552 674 p3 = oe_prev_point(e, p1); 675 if (p3 == NULL) 676 return; 677 678 tmp = owl_malloc(p2 - p3 + 5); 679 *tmp = '\0'; 680 strncat(tmp, p1, p2 - p1); 681 strncat(tmp, p3, p1 - p3); 682 strncpy(p3, tmp, p2 - p3); 683 owl_free(tmp); 684 oe_set_index(e, p3 - e->buff); 553 tmp = owl_malloc((end - start) + 1); 554 tmp[(end - start)] = 0; 555 memcpy(tmp, middle, end - middle); 556 memcpy(tmp + (end - middle), start, middle - start); 557 558 owl_editwin_point_move(e, -1); 559 owl_editwin_replace(e, 2, tmp); 685 560 } 686 561 … … 688 563 * right 689 564 */ 690 void owl_editwin_insert_string(owl_editwin *e, char *string) 691 { 692 char *p; 693 gunichar c; 694 if (!g_utf8_validate(string, -1, NULL)) { 695 owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string."); 696 return; 697 } 698 p = string; 699 c = g_utf8_get_char(p); 700 while (c) { 701 _owl_editwin_process_char(e, c); 702 p = g_utf8_next_char(p); 703 c = g_utf8_get_char(p); 704 } 705 } 706 707 /* write 'string' at the current point, overwriting text that is 708 * already there 709 */ 710 711 static void owl_editwin_overwrite_string(owl_editwin *e, char *string) 712 { 713 char *p; 714 gunichar c; 715 716 if (!g_utf8_validate(string, -1, NULL)) { 717 owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string."); 718 return; 719 } 720 p = string; 721 c = g_utf8_get_char(p); 722 while (c) { 723 owl_editwin_overwrite_char(e, c); 724 p = g_utf8_next_char(p); 725 c = g_utf8_get_char(p); 726 } 565 void owl_editwin_insert_string(owl_editwin *e, char *s) 566 { 567 owl_editwin_replace(e, 0, s); 727 568 } 728 569 … … 788 629 { 789 630 char *p; 790 /* It would be awfully nice if we could do UTF-8 comparisons */ 791 for (p = set; *p != 0; p ++)792 if (owl_editwin_get_char_at_point(e) == *p)631 632 for (p = set; *p != 0; p = g_utf8_find_next_char(p, NULL)) 633 if (owl_editwin_get_char_at_point(e) == g_utf8_get_char(p)) 793 634 return 1; 794 635 return 0; … … 902 743 } 903 744 745 int owl_editwin_forward_word(owl_editwin *e) 746 { 747 int distance; 748 /* if we're starting on a space, find the first non-space */ 749 distance = owl_editwin_move_if_in(e, 1, WHITESPACE); 750 751 /* now find the end of this word */ 752 distance += owl_editwin_move_if_not_in(e, 1, WHITESPACE); 753 754 return distance; 755 } 756 904 757 void owl_editwin_move_to_nextword(owl_editwin *e) 905 758 { 906 /* if we're starting on a space, find the first non-space */ 907 owl_editwin_move_if_in(e, 1, WHITESPACE); 908 909 /* now find the end of this word */ 910 owl_editwin_move_if_not_in(e, 1, WHITESPACE); 759 owl_editwin_forward_word(e); 911 760 } 912 761 913 762 /* go backwards to the last non-space character 914 763 */ 915 void owl_editwin_move_to_previousword(owl_editwin *e)764 int owl_editwin_backward_word(owl_editwin *e) 916 765 { 917 766 oe_excursion x; 767 int distance = 0; 768 int further = 0; 918 769 int beginning; 919 770 /* if in middle of word, beginning of word */ … … 923 774 if (owl_editwin_is_char_in(e, WHITESPACE)) { 924 775 /* if in whitespace past end of word, find a word , the find the beginning*/ 925 owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last926 character of the word */776 distance += owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last 777 character of the word */ 927 778 oe_save_excursion(e, &x); 928 779 /* are we at the beginning of a word? */ … … 931 782 oe_restore_excursion(e, &x); 932 783 if (beginning) 933 return ;784 return distance; 934 785 } else { 935 786 /* in the middle of the word; */ 936 787 oe_save_excursion(e, &x); 937 owl_editwin_point_move(e, -1);788 further += owl_editwin_point_move(e, -1); 938 789 if (owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */ 939 owl_editwin_move_to_previousword(e); /* previous case */940 return ;790 distance += owl_editwin_backward_word(e); /* previous case */ 791 return distance + further; 941 792 } else { 942 793 oe_restore_excursion(e, &x); 943 794 } 944 795 } 945 owl_editwin_move_if_not_in(e, -1, WHITESPACE);796 distance += owl_editwin_move_if_not_in(e, -1, WHITESPACE); 946 797 /* will go past */ 947 798 if (e->index > e->lock) 948 owl_editwin_point_move(e, 1); 799 distance += owl_editwin_point_move(e, 1); 800 return distance; 801 } 802 803 void owl_editwin_move_to_previousword(owl_editwin *e) 804 { 805 owl_editwin_backward_word(e); 949 806 } 950 807 … … 952 809 { 953 810 oe_excursion x; 954 int end;811 int distance; 955 812 956 813 oe_save_excursion(e, &x); 957 owl_editwin_move_to_nextword(e); 958 end = e->index; 814 distance = owl_editwin_forward_word(e); 959 815 oe_restore_excursion(e, &x); 960 _owl_editwin_remove_bytes(e, end - e->index);816 owl_editwin_replace(e, distance, ""); 961 817 } 962 818 … … 964 820 { 965 821 /* go backwards to the last non-space character, then delete chars */ 966 int startpos, endpos; 967 968 startpos = e->index; 969 owl_editwin_move_to_previousword(e); 970 endpos = e->index; 971 _owl_editwin_remove_bytes(e, startpos-endpos); 822 int distance; 823 824 distance = owl_editwin_backward_word(e); 825 owl_editwin_replace(e, -distance, ""); 972 826 } 973 827 … … 980 834 { 981 835 oe_excursion x; 982 int end;836 int distance; 983 837 984 838 oe_save_excursion(e, &x); 985 owl_editwin_move_to_line_end(e); 986 end = e->index; 839 distance = owl_editwin_move_to_end_of_line(e); 987 840 oe_restore_excursion(e, &x); 988 if (end - e->index) 989 _owl_editwin_remove_bytes(e, end - e->index); 990 else if (end < e->bufflen) 991 _owl_editwin_remove_bytes(e, 1); 841 owl_editwin_replace(e, distance ? distance : 1, ""); 992 842 } 993 843 … … 1127 977 } 1128 978 1129 static void _owl_editwin_process_char(owl_editwin *e, gunichar j)1130 {1131 if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13)) || j==9 ) {1132 owl_editwin_insert_char(e, j);1133 }1134 }1135 1136 1137 979 void owl_editwin_process_char(owl_editwin *e, owl_input j) 1138 980 { 1139 if (j.ch == ERR) return; 981 #if 0 982 int i, ret, len; 983 #endif 984 char tmp[7]; 985 986 if (j.ch == ERR) 987 return; 1140 988 /* Ignore ncurses control characters. */ 1141 989 if (j.ch < 0x100) { 1142 _owl_editwin_process_char(e, j.uch); 990 if (!(g_unichar_iscntrl(j.uch) && (j.uch != 10) && (j.uch != 13)) || j.uch==9 ) { 991 memset(tmp, 0, 7); 992 993 /* \r is \n */ 994 if (j.uch == '\r') { 995 j.uch = '\n'; 996 } 997 998 if (j.uch == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) { 999 return; 1000 } 1001 1002 g_unichar_to_utf8(j.uch, tmp); 1003 owl_editwin_replace(e, 0, tmp); 1004 1005 #if 0 /* XXX */ 1006 /* If we're going to insert at the last column do word wrapping, unless it's a \n */ 1007 if ((e->buffx + 1 == e->wrapcol) && (j.uch != '\n')) { 1008 ret = _owl_editwin_linewrap_word(e); 1009 if (ret == -1) { 1010 /* we couldn't wrap, insert a hard newline instead */ 1011 owl_editwin_replace(e, 0, "\n"); 1012 } 1013 } 1014 #endif 1015 } 1143 1016 } 1144 1017 }
Note: See TracChangeset
for help on using the changeset viewer.