Changeset bd1a1ae


Ignore:
Timestamp:
Jul 11, 2009, 1:14:32 PM (15 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
e20d8179
Parents:
a556caa
git-author:
Karl Ramm <kcr@1ts.org> (06/07/09 05:21:45)
git-committer:
Nelson Elhage <nelhage@mit.edu> (07/11/09 13:14:32)
Message:
Basic new redisplay + point at end of buffer + tabs

The core of the new redisplay. Now featuring tabs, and properly
wrapping lines.

And I kludged around the problem with the point being at the end of
the buffer.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • editwin.c

    ra556caa rbd1a1ae  
    263263}
    264264static void owl_editwin_reframe(owl_editwin *e) { /* noproto */
    265    e->topindex = 0; /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
     265  e->topindex = 0; /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
    266266}
    267267
     
    270270void owl_editwin_redisplay(owl_editwin *e, int update)
    271271{
    272   int x = 0, y = 0;
    273   char *ptop, *ptr2, *pbot, *buff;
    274   char *target;
    275   int i;
     272  int x = -1, y = -1;  char *p;
     273  int width, line, index, lineindex, cw;
     274  gunichar c;
    276275
    277276  werase(e->curswin);
    278   wmove(e->curswin, 0, 0);
    279 
    280   if (e->topindex < 0 || e->index < e->topindex)
    281     owl_editwin_reframe(e);
    282 
    283   ptop = e->buff + e->topindex;
    284   target = e->buff + e->index;
    285 
    286   /* find the ending point and store it in pbot */
    287   ptr2 = ptop;
    288   pbot = ptop;
    289   for (i = 0; i < e->winlines; i++) {
    290     pbot = strchr(ptr2, '\n');
    291     if (!pbot) {
    292       /* we've hit the last line */
    293       /* print everything to the end */
    294       pbot = e->buff + e->bufflen - 1;
    295       pbot--;
    296       break;
    297     }
    298     ptr2 = pbot + 1;
    299   }
    300   pbot += 2;
    301 
    302   buff = owl_malloc(pbot - ptop + 50);
    303   strncpy(buff, ptop, pbot - ptop);
    304   buff[pbot - ptop] = '\0';
    305   if (e->echochar == '\0') {
    306     waddstr(e->curswin, buff);
    307   } else {
    308     /* translate to echochar, *except* for the locktext */
    309     int len;
    310     int dolocklen = e->lock - (ptop - e->buff);
    311     char *locktext;
    312     char tmp = e->buff[dolocklen];
    313 
    314     e->buff[dolocklen] = '\0';
    315     locktext = owl_strdup(e->buff);
    316     e->buff[dolocklen] = tmp;
    317 
    318     waddstr(e->curswin, locktext);
     277
     278  do {
     279    if (e->topindex == -1 || e->index < e->topindex)
     280      owl_editwin_reframe(e);
    319281   
    320     len = strlen(buff);
    321     for (i = 0; i < len-dolocklen; i++) {
    322       waddch(e->curswin, e->echochar);
    323     }
    324   }
    325   { /* locates the point */
    326     char *ptr1, *ptr2;
    327     gunichar c;
    328 
    329     ptr1 = ptop;
    330     /* target sanitizing */
    331     if ((target[0] & 0x80) && (~target[0] & 0x40)) {
    332       /* middle of a utf-8 character, back up to previous character. */
    333       target = g_utf8_find_prev_char(e->buff, target);
    334     }
    335     c = g_utf8_get_char(target);
    336     while (g_unichar_ismark(c) && target > e->buff) {
    337       /* Adjust the target off of combining characters and the like. */
    338       target = g_utf8_find_prev_char(e->buff, target);
    339       c = g_utf8_get_char(target);
    340     }
    341     /* If we start with a mark, something is wrong.*/
    342     if (g_unichar_ismark(c)) return;
    343    
    344     /* Now our target should be acceptable. */
    345     ptr2 = strchr(ptr1, '\n');
    346     while (ptr2 != NULL && ptr2 < target) {
    347       ++y;
    348       ptr1 = ptr2 + 1;
    349       ptr2 = strchr(ptr1, '\n');
    350     }
    351     ptr2 = ptr1;
    352     while (ptr2 != NULL && ptr2 < target) {
    353       c = g_utf8_get_char(ptr2);
    354       x += mk_wcwidth(c);
    355       ptr2 = g_utf8_next_char(ptr2);
    356     }
    357   }
    358   wmove(e->curswin, y, x);
     282    line = 0;
     283    index = e->topindex;
     284    while(line < e->winlines) {
     285      width = 0;
     286      lineindex = index;
     287      /* okay, we want to find no nore that e->wincols cells or a \n */
     288      /* then waddnstr it */
     289      /* and as a side effect, noting where the cursor should end up */
     290      while(1) {
     291        c = g_utf8_get_char(e->buff + index);
     292        if (index == e->index)
     293          y = line, x = width;
     294        if (c == 9) /* TAB */
     295          cw = 8 - width % 8;
     296        else
     297          cw = mk_wcwidth(c);
     298        if (width + cw > e->wincols)
     299          break;
     300        width += cw;
     301        p = g_utf8_find_next_char(e->buff + index, e->buff + e->bufflen);
     302        if (p == NULL) /* we ran off the end */
     303          break;
     304        index = p - e->buff;
     305        if (c == '\n')
     306          break;
     307      }
     308      if (index - lineindex)
     309        mvwaddnstr(e->curswin, line, 0,
     310                   e->buff + lineindex,
     311                   index - lineindex);
     312      if (p == NULL)
     313        break;
     314      line++;
     315    }
     316    if (x == -1) {
     317      if (p == NULL && c != '\n')
     318        y = line, x = width;
     319      else if (p == NULL)
     320        y = line + 1, x = 0;
     321      else
     322        e->topindex = -1; /* force a reframe */
     323    }
     324  } while(x == -1);
     325 
     326  if (x != -1)
     327    wmove(e->curswin, y, x);
    359328  wnoutrefresh(e->curswin);
    360329  if (update == 1)
    361330    doupdate();
    362   owl_free(buff);
    363331}
    364332
     
    674642{
    675643  char *p, *boundary;
    676   int change, d = 0;
     644  int change, index, d = 0;
    677645
    678646  change = MAX(delta, - delta);
    679647  p = e->buff + e->index;
    680648
    681   boundary = e->buff + (delta > 0 ? e->bufflen : e->lock);
     649  boundary = e->buff + (delta > 0 ? (e->bufflen + 1) : e->lock);
    682650
    683651  while (d < change && p != NULL) {
     
    691659        p = g_utf8_find_prev_char(boundary, p);
    692660    }
    693     if (p != NULL) {
    694       e->index = p - e->buff;
    695       d++;
     661    if (p != NULL) {
     662      index = p - e->buff;
     663      if (index != e->index) { /* XXX rethink the loop termination condition
     664                                  above */
     665        e->index = index;
     666        d++;
     667      } else
     668        break;
    696669    }
    697670  }
     
    10811054void _owl_editwin_process_char(owl_editwin *e, gunichar j)
    10821055{
    1083   if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
     1056  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13)) || j==9 ) {
    10841057    owl_editwin_insert_char(e, j);
    10851058  }
Note: See TracChangeset for help on using the changeset viewer.