Changeset a556caa


Ignore:
Timestamp:
Jul 11, 2009, 1:14:24 PM (12 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
bd1a1ae
Parents:
a45786e
git-author:
Karl Ramm <kcr@1ts.org> (07/07/09 23:03:19)
git-committer:
Nelson Elhage <nelhage@mit.edu> (07/11/09 13:14:24)
Message:
Mostly refactor the editwin to use a linear buffer position.

Use a linear buffer positino to keep track of the point, rather than
(x, y).

In addition, make the editwin structure private to editwin.c. (No
abstraction violation for you!)

Add some abstractions for pointer movement, and use them in some places.
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • commands.c

    r73ba824 ra556caa  
    26582658  owl_function_makemsg("Command cancelled.");
    26592659
    2660   if(e->echochar == 0) {
     2660  if(owl_editwin_get_echochar(e) == 0) {
    26612661    hist=owl_editwin_get_history(e);
    26622662    owl_history_store(hist, owl_editwin_get_text(e));
  • editwin.c

    ra45786e ra556caa  
    77static const char fileIdent[] = "$Id$";
    88
     9struct _owl_editwin { /*noproto*/
     10  char *buff;
     11  owl_history *hist;
     12  int bufflen;
     13  int allocated;
     14  int index;
     15  int goal_column;
     16  int topindex;
     17  int winlines, wincols, fillcol, wrapcol;
     18  WINDOW *curswin;
     19  int style;
     20  int lock;
     21  int dotsend;
     22  int echochar;
     23
     24  char *command;
     25  void (*callback)(struct _owl_editwin*);
     26  void *cbdata;
     27};
     28
     29typedef struct { /*noproto*/
     30  int index;
     31  int goal_column;
     32} _owl_editwin_excursion;
     33
    934#define INCR 5000
     35
     36#define WHITESPACE " \n\t"
     37
     38owl_editwin *owl_editwin_allocate(void) {
     39  return owl_malloc(sizeof(owl_editwin));
     40}
    1041
    1142/* initialize the editwin e.
     
    1950  e->hist=hist;
    2051  e->allocated=INCR;
    21   e->buffx=0;
    22   e->buffy=0;
    23   e->topline=0;
     52  e->index = 0;
     53  e->goal_column = -1;
     54  e->topindex=0;
    2455  e->winlines=winlines;
    2556  e->wincols=wincols;
     
    106137}
    107138
    108 void* owl_editwin_get_cbdata(owl_editwin *e) {
     139void *owl_editwin_get_cbdata(owl_editwin *e) {
    109140  return e->cbdata;
    110141}
     
    135166void owl_editwin_set_locktext(owl_editwin *e, char *text)
    136167{
    137   e->buffx=0;
    138   e->buffy=0;
     168  e->index = 0;
    139169  owl_editwin_overwrite_string(e, text);
    140170  owl_editwin_overwrite_char(e, '\0');
    141171  e->lock=strlen(text);
    142   _owl_editwin_set_xy_by_index(e, e->lock);
     172  e->index = e->lock;
    143173  owl_editwin_redisplay(e, 0);
    144174}
     
    167197        e->bufflen=ptr - e->buff;
    168198        e->buff[e->bufflen]='\0';
    169         e->buffx=0;
    170         e->buffy=0;
     199        e->index = 0;
    171200      }
    172201    }
     
    223252  e->buff=owl_realloc(e->buff, e->allocated+INCR);
    224253  if (!e->buff) {
    225     /* error */
     254    /* error *//*XXXXXXXXXXXXXXXX*/
    226255    return;
    227256  }
     
    231260void owl_editwin_recenter(owl_editwin *e)
    232261{
    233   e->topline=e->buffy-(e->winlines/2);
    234   if (e->topline<0) e->topline=0;
    235   if (e->topline>owl_editwin_get_numlines(e)) e->topline=owl_editwin_get_numlines(e);
     262  e->topindex = -1;
     263}
     264static void owl_editwin_reframe(owl_editwin *e) { /* noproto */
     265   e->topindex = 0; /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
    236266}
    237267
     
    240270void owl_editwin_redisplay(owl_editwin *e, int update)
    241271{
    242  
    243   char *ptr1, *ptr2, *ptr3, *buff;
     272  int x = 0, y = 0;
     273  char *ptop, *ptr2, *pbot, *buff;
     274  char *target;
    244275  int i;
    245276
     
    247278  wmove(e->curswin, 0, 0);
    248279
    249   /* start at topline */
    250   ptr1 = e->buff;
    251   for (i = 0; i < e->topline; i++) {
    252     ptr2 = strchr(ptr1, '\n');
    253     if (!ptr2) {
    254       /* we're already on the last line */
    255       break;
    256     }
    257     ptr1 = ptr2 + 1;
    258   }
    259   /* ptr1 now stores the starting point */
    260 
    261   /* find the ending point and store it in ptr3 */
    262   ptr2 = ptr1;
    263   ptr3 = ptr1;
     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;
    264289  for (i = 0; i < e->winlines; i++) {
    265     ptr3 = strchr(ptr2, '\n');
    266     if (!ptr3) {
     290    pbot = strchr(ptr2, '\n');
     291    if (!pbot) {
    267292      /* we've hit the last line */
    268293      /* print everything to the end */
    269       ptr3 = e->buff + e->bufflen - 1;
    270       ptr3--;
     294      pbot = e->buff + e->bufflen - 1;
     295      pbot--;
    271296      break;
    272297    }
    273     ptr2 = ptr3 + 1;
    274   }
    275   ptr3 += 2;
    276 
    277   buff = owl_malloc(ptr3 - ptr1 + 50);
    278   strncpy(buff, ptr1, ptr3 - ptr1);
    279   buff[ptr3 - ptr1] = '\0';
     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';
    280305  if (e->echochar == '\0') {
    281306    waddstr(e->curswin, buff);
     
    283308    /* translate to echochar, *except* for the locktext */
    284309    int len;
    285     int dolocklen = e->lock - (ptr1 - e->buff);
     310    int dolocklen = e->lock - (ptop - e->buff);
    286311    char *locktext;
    287312    char tmp = e->buff[dolocklen];
     
    298323    }
    299324  }
    300   wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
     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);
    301359  wnoutrefresh(e->curswin);
    302   if (update == 1) {
     360  if (update == 1)
    303361    doupdate();
    304   }
    305362  owl_free(buff);
    306363}
     
    309366void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
    310367{
    311   int i = _owl_editwin_get_index_from_xy(e) + n;
     368  int i = e->index + n;
    312369  for (; i < e->bufflen; i++) {
    313370    e->buff[i-n] = e->buff[i];
     
    321378void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
    322379{
    323   int i, z;
     380  int i;
    324381
    325382  if ((e->bufflen + n) > (e->allocated - 5)) {
     
    327384  }
    328385
    329   z = _owl_editwin_get_index_from_xy(e);
    330 
    331   if(z != e->bufflen) {
    332     for (i = e->bufflen + n - 1; i > z; i--) {
     386  if(e->index != e->bufflen) {
     387    for (i = e->bufflen + n - 1; i > e->index; i--) {
    333388      e->buff[i] = e->buff[i - n];
    334389    }
     
    353408  start = e->buff + e->lock;
    354409
    355   ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     410  ptr1 = e->buff + e->index;
    356411  ptr1 = g_utf8_find_prev_char(start, ptr1);
    357412
     
    361416      if (c != ' ') {
    362417        i = ptr1 - e->buff;
    363         _owl_editwin_set_xy_by_index(e, i);
     418        e->index = i;
    364419        _owl_editwin_insert_bytes(e, 1);
    365420        /* _owl_editwin_insert_bytes may move e->buff. */
     
    382437void owl_editwin_insert_char(owl_editwin *e, gunichar c)
    383438{
    384   int z, i, ret, len;
     439  int i, ret, len;
    385440  char tmp[6];
    386441  memset(tmp, '\0', 6);
     
    405460  }
    406461
    407   /* get the insertion point */
    408   z = _owl_editwin_get_index_from_xy(e);
    409 
    410462  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
     463#if 0 /* XXX */
    411464  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
    412465    ret = _owl_editwin_linewrap_word(e);
     
    416469    }
    417470  }
     471#endif
    418472
    419473  /* shift all the other characters right */
     
    422476  /* insert the new character */
    423477  for(i = 0; i < len; i++) {
    424     e->buff[z + i] = tmp[i];
     478    e->buff[e->index + i] = tmp[i];
    425479  }
    426480
    427481  /* advance the cursor */
    428   z += len;
    429   _owl_editwin_set_xy_by_index(e, z);
     482  e->index += len;
    430483}
    431484
     
    433486void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
    434487{
    435   int z, oldlen, newlen, i;
    436   char tmp[6];
     488  int oldlen, newlen, i;
     489  char tmp[6], *t;
    437490  memset(tmp, '\0', 6);
    438491
     
    451504  newlen = strlen(tmp);
    452505
    453   z = _owl_editwin_get_index_from_xy(e);
    454   {
    455     char *t = g_utf8_find_next_char(e->buff + z, NULL);
    456     oldlen = (t ? (t - (e->buff + z)) : 0);
    457   }
     506  t = g_utf8_find_next_char(e->buff + e->index, NULL);
     507  oldlen = (t ? (t - (e->buff + e->index)) : 0);
    458508
    459509  /* only if we are at the end of the buffer do we create new space here */
    460   if (z == e->bufflen) {
     510  if (e->index == e->bufflen) {
    461511    if ((e->bufflen+newlen) > (e->allocated-5)) {
    462512      _owl_editwin_addspace(e);
     
    472522  /* Overwrite the old char*/
    473523  for (i = 0; i < newlen; i++) {
    474     e->buff[z+i] = tmp[i];
     524    e->buff[e->index + i] = tmp[i];
    475525  }
    476526       
    477527  /* housekeeping */
    478   if (z == e->bufflen) {
     528  if (e->index == e->bufflen) {
    479529    e->bufflen += newlen;
    480530    e->buff[e->bufflen] = '\0';
     
    482532 
    483533  /* advance the cursor */
    484   z += newlen;
    485   _owl_editwin_set_xy_by_index(e, z);
     534  e->index += newlen;
    486535}
    487536
     
    491540void owl_editwin_delete_char(owl_editwin *e)
    492541{
    493   int z;
    494542  char *p1, *p2;
    495543  gunichar c;
     
    497545  if (e->bufflen == 0) return;
    498546 
    499   /* get the deletion point */
    500   z = _owl_editwin_get_index_from_xy(e);
    501 
    502   if (z == e->bufflen) return;
    503 
    504   p1 = e->buff + z;
     547  if (e->index == e->bufflen) return;
     548
     549  p1 = e->buff + e->index;
    505550  p2 = g_utf8_next_char(p1);
    506551  c = g_utf8_get_char(p2);
     
    519564void owl_editwin_transpose_chars(owl_editwin *e)
    520565{
    521   int z;
    522566  char *p1, *p2, *p3, *tmp;
    523567
    524568  if (e->bufflen == 0) return;
    525569 
    526   /* get the cursor point */
    527   z = _owl_editwin_get_index_from_xy(e);
    528 
    529   if (z == e->bufflen) {
     570  if (e->index == e->bufflen) {
    530571    /* point is after last character */
    531     z--;
     572    e->index--;
    532573  } 
    533574
    534   if (z - 1 < e->lock) {
     575  if (e->index - 1 < e->lock) {
    535576    /* point is at beginning of buffer, do nothing */
    536577    return;
     
    538579
    539580  /* Transpose two utf-8 unicode glyphs. */
    540   p1 = e->buff + z;
     581  p1 = e->buff + e->index;
    541582
    542583  p2 = g_utf8_find_next_char(p1, NULL);
     
    558599  strncpy(p3, tmp, p2 - p3);
    559600  owl_free(tmp);
    560   _owl_editwin_set_xy_by_index(e, p3 - e->buff);
     601  e->index = p3 - e->buff;
    561602}
    562603
     
    603644}
    604645
    605 /* get the index into e->buff for the current cursor
    606  * position.
    607  */
    608 int _owl_editwin_get_index_from_xy(owl_editwin *e)
    609 {
    610   int i;
    611   char *ptr1, *ptr2;
    612   gunichar c;
    613 
    614   if (e->bufflen == 0) return(0);
    615  
    616   /* first go to the yth line */
    617   ptr1 = e->buff;
    618   for (i = 0; i < e->buffy; i++) {
    619     ptr2= strchr(ptr1, '\n');
    620     if (!ptr2) {
    621       /* we're already on the last line */
    622       break;
    623     }
    624     ptr1 = ptr2 + 1;
    625   }
    626 
    627   /* now go to the xth cell */
    628   ptr2 = ptr1;
    629   i = 0;
    630   while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
    631     c = g_utf8_get_char(ptr2);
    632     i += (c == '\n' ? 1 : mk_wcwidth(c));
    633     ptr2 = g_utf8_next_char(ptr2);
    634   }
    635   while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
    636     ptr2 = g_utf8_next_char(ptr2);
    637   }
    638   if (ptr2 == NULL) return e->bufflen;
    639   return(ptr2 - e->buff);
    640 }
    641 
    642 /* We assume x,y are not set to point to a mid-char */
    643 gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
    644 {
    645   return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
    646 }
    647 
    648 
    649 void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
    650 {
    651   char *ptr1, *ptr2, *target;
    652   gunichar c;
    653 
    654   e->buffx = 0;
    655   e->buffy = 0;
    656 
    657   ptr1 = e->buff;
    658   target = ptr1 + index;
    659   /* target sanitizing */
    660   if ((target[0] & 0x80) && (~target[0] & 0x40)) {
    661     /* middle of a utf-8 character, back up to previous character. */
    662     target = g_utf8_find_prev_char(e->buff, target);
    663   }
    664   c = g_utf8_get_char(target);
    665   while (g_unichar_ismark(c) && target > e->buff) {
    666     /* Adjust the target off of combining characters and the like. */
    667     target = g_utf8_find_prev_char(e->buff, target);
    668     c = g_utf8_get_char(target);
    669   }
    670   /* If we start with a mark, something is wrong.*/
    671   if (g_unichar_ismark(c)) return;
    672 
    673   /* Now our target should be acceptable. */
    674   ptr2 = strchr(ptr1, '\n');
    675   while (ptr2 != NULL && ptr2 < target) {
    676     e->buffy++;
    677     ptr1 = ptr2 + 1;
    678     ptr2 = strchr(ptr1, '\n');
    679   }
    680   ptr2 = ptr1;
    681   while (ptr2 != NULL && ptr2 < target) {
    682     c = g_utf8_get_char(ptr2);
    683     e->buffx += mk_wcwidth(c);
    684     ptr2 = g_utf8_next_char(ptr2);
    685   }
    686 }
    687 
    688 int _owl_editwin_cursor_adjustment(owl_editwin *e)
    689 {
    690   char *ptr1, *ptr2;
    691   gunichar c;
    692   int x, i;
    693 
    694   /* Find line */
    695   ptr1 = e->buff;
    696   ptr2 = strchr(ptr1, '\n');
    697   for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
    698     ptr1 = ptr2 + 1;
    699     ptr2 = strchr(ptr1, '\n');
    700   }
    701   ptr2 = ptr1;
    702 
    703   /* Find char */
    704   x = 0;
    705   while (ptr2 != NULL && x < e->buffx) {
    706     if (*ptr2 == '\n') return 0;
    707     c = g_utf8_get_char(ptr2);
    708     x += mk_wcwidth(c);
    709     ptr2 = g_utf8_next_char(ptr2);
    710   }
    711  
    712   /* calculate x offset */
    713   return x - e->buffx;
     646/* We assume index is not set to point to a mid-char */
     647gunichar _owl_editwin_get_char_at_point(owl_editwin *e)
     648{
     649  return g_utf8_get_char(e->buff + e->index);
     650}
     651
     652void owl_editwin_save_excursion(owl_editwin *e, _owl_editwin_excursion *x) /*noproto*/
     653{
     654  x->index = e->index;
     655  x->goal_column = e->goal_column;
     656}
     657
     658void owl_editwin_restore_excursion(owl_editwin *e, _owl_editwin_excursion *x) /*noproto*/
     659{
     660  e->index = x->index;
     661  e->goal_column = x->goal_column;
    714662}
    715663
     
    718666  /* if we happen to have the cursor over locked text
    719667   * move it to be out of the locktext region */
    720   if (_owl_editwin_get_index_from_xy(e) < e->lock) {
    721     _owl_editwin_set_xy_by_index(e, e->lock);
    722   }
     668  if (e->index < e->lock) {
     669    e->index = e->lock;
     670  }
     671}
     672
     673int owl_editwin_point_move(owl_editwin *e, int delta) /*noproto*/
     674{
     675  char *p, *boundary;
     676  int change, d = 0;
     677
     678  change = MAX(delta, - delta);
     679  p = e->buff + e->index;
     680
     681  boundary = e->buff + (delta > 0 ? e->bufflen : e->lock);
     682
     683  while (d < change && p != NULL) {
     684    if (delta > 0) {
     685      p = g_utf8_find_next_char(p, boundary);
     686      while (p && g_unichar_ismark(g_utf8_get_char(p)))
     687        p = g_utf8_find_next_char(p, boundary);
     688    } else {
     689      p = g_utf8_find_prev_char(boundary, p);
     690      while (p && g_unichar_ismark(g_utf8_get_char(p)))
     691        p = g_utf8_find_prev_char(boundary, p);
     692    }
     693    if (p != NULL) {
     694      e->index = p - e->buff;
     695      d++;
     696    }
     697  }
     698
     699  if (delta)
     700    e->goal_column = -1;
     701
     702  return delta > 0 ? d : -d;
     703}
     704
     705int owl_editwin_at_beginning_of_buffer(owl_editwin *e) {
     706  if (e->index == e->lock)
     707    return 1;
     708
     709  return 0;
     710}
     711
     712int owl_at_end_of_buffer(owl_editwin *e) {
     713  if (e->index == e->bufflen)
     714    return 1;
     715
     716  return 0;
     717}
     718
     719int owl_editwin_at_beginning_of_line(owl_editwin *e) /*noproto*/
     720{
     721  _owl_editwin_excursion x;
     722  int ret;
     723
     724  if (owl_editwin_at_beginning_of_buffer(e))
     725    return 1;
     726
     727  owl_editwin_save_excursion(e, &x);
     728  owl_editwin_point_move(e, -1);
     729  ret = (_owl_editwin_get_char_at_point(e) == '\n');
     730  owl_editwin_restore_excursion(e, &x);
     731
     732  return ret;
     733}
     734
     735int _owl_editwin_is_char_in(owl_editwin *e, char *set) /*noproto*/
     736{
     737  char *p;
     738  /* It would be awfully nice if we could do UTF-8 comparisons */
     739  for (p = set; *p != 0; p++)
     740    if (_owl_editwin_get_char_at_point(e) == *p)
     741      return 1;
     742  return 0;
     743}
     744
     745int owl_editwin_move_if_in(owl_editwin *e, int delta, char *set) /*noproto*/
     746{
     747  int change, distance = 0;
     748  while (_owl_editwin_is_char_in(e, set)) {
     749    change = owl_editwin_point_move(e, delta);
     750    distance += change;
     751    if (change == 0)
     752      break;
     753  }
     754  return distance;
     755}
     756
     757int owl_editwin_move_if_not_in(owl_editwin *e, int delta, char *set) /*noproto*/
     758{
     759  int change, distance = 0;
     760  while (!_owl_editwin_is_char_in(e, set)) {
     761    change = owl_editwin_point_move(e, delta);
     762    distance += change;
     763    if (change == 0)
     764      break;
     765  }
     766  return distance;
     767}
     768
     769int owl_editwin_move_to_beginning_of_line(owl_editwin *e) /* noproto */
     770{
     771  int distance = 0;
     772
     773  if (!owl_editwin_at_beginning_of_line(e)) {
     774    /* move off the \n if were at the end of a line */
     775    distance += owl_editwin_point_move(e, -1);
     776    distance += owl_editwin_move_if_not_in(e, -1, "\n");
     777    if (distance && !owl_editwin_at_beginning_of_buffer(e))
     778      distance += owl_editwin_point_move(e, 1);
     779  }
     780
     781  return distance;
     782}
     783 
     784int owl_editwin_move_to_end_of_line(owl_editwin *e) /* noproto */
     785{
     786  return owl_editwin_move_if_not_in(e, 1, "\n");
     787}
     788
     789int owl_editwin_line_move(owl_editwin *e, int delta) /*noproto*/
     790{
     791  int goal_column, change, ll, count = 0, distance = 0;
     792
     793  if (e->goal_column == -1) {
     794    if (owl_editwin_at_beginning_of_line(e))
     795      goal_column = 0;
     796    else {
     797      goal_column = -owl_editwin_move_if_not_in(e, -1, "\n");
     798      if (!owl_editwin_at_beginning_of_buffer(e))
     799        goal_column -= owl_editwin_point_move(e, 1);
     800    }
     801  } else
     802    goal_column = e->goal_column;
     803
     804  change = MAX(delta, -delta);
     805
     806  distance += owl_editwin_move_to_beginning_of_line(e);
     807
     808  while(count < change) {
     809    if (delta > 0) {
     810      distance += owl_editwin_move_if_not_in(e, 1, "\n");
     811      distance += owl_editwin_point_move(e, 1);
     812    } else {
     813      /* I really want to assert delta < 0 here */
     814      distance += owl_editwin_point_move(e, -1); /* to the newline on
     815                                                    the previous line */
     816      distance += owl_editwin_move_to_beginning_of_line(e);
     817    }
     818    count++;
     819  }
     820
     821  distance += (ll = owl_editwin_move_to_end_of_line(e));
     822  if (ll > goal_column)
     823    distance += owl_editwin_point_move(e, goal_column - ll);
     824
     825  e->goal_column = goal_column;
     826
     827  return distance;
    723828}
    724829
     
    728833   * and shift later chars left
    729834   */
    730   if (_owl_editwin_get_index_from_xy(e) > e->lock) {
    731     owl_editwin_key_left(e);
     835  if(owl_editwin_point_move(e, -1))
    732836    owl_editwin_delete_char(e);
    733   }
    734   owl_editwin_adjust_for_locktext(e);
    735837}
    736838
    737839void owl_editwin_key_up(owl_editwin *e)
    738840{
    739   if (e->buffy > 0) e->buffy--;
    740   if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
    741     e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    742   }
    743 
    744   /* do we need to scroll? */
    745   if (e->buffy-e->topline < 0) {
    746     e->topline-=e->winlines/2;
    747   }
    748 
    749   owl_editwin_adjust_for_locktext(e);
     841  owl_editwin_line_move(e, -1);
    750842}
    751843
    752844void owl_editwin_key_down(owl_editwin *e)
    753845{
    754   /* move down if we can */
    755   if (e->buffy+1 < owl_editwin_get_numlines(e)) e->buffy++;
    756 
    757   /* if we're past the last character move back */
    758   if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
    759     e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    760   }
    761 
    762   /* do we need to scroll? */
    763   if (e->buffy-e->topline > e->winlines) {
    764     e->topline+=e->winlines/2;
    765   }
    766 
    767   /* adjust for locktext */
    768   owl_editwin_adjust_for_locktext(e);
     846  owl_editwin_line_move(e, 1);
    769847}
    770848
    771849void owl_editwin_key_left(owl_editwin *e)
    772850{
    773   int i;
    774   char * p;
    775   i = _owl_editwin_get_index_from_xy(e);
    776   p = e->buff + i;
    777   p = g_utf8_find_prev_char(e->buff, p);
    778   while (p && g_unichar_ismark(g_utf8_get_char(p))) {
    779     p = g_utf8_find_prev_char(e->buff, p);
    780   }
    781   if (p == NULL) p = e->buff;
    782   _owl_editwin_set_xy_by_index(e, p - e->buff);
    783 
    784   if (e->buffy - e->topline < 0) {
    785     e->topline -= e->winlines / 2;
    786   }
    787 
    788   /* make sure to avoid locktext */
    789   owl_editwin_adjust_for_locktext(e);
     851  owl_editwin_point_move(e, -1);
    790852}
    791853
    792854void owl_editwin_key_right(owl_editwin *e)
    793855{
    794   int i;
    795   char * p;
    796   i = _owl_editwin_get_index_from_xy(e);
    797   p = e->buff + i;
    798   p = g_utf8_find_next_char(p, NULL);
    799   while (p && g_unichar_ismark(g_utf8_get_char(p))) {
    800     p = g_utf8_find_next_char(p, NULL);
    801   }
    802   if (p == NULL) {
    803     _owl_editwin_set_xy_by_index(e, e->bufflen);
    804   }
    805   else {
    806     _owl_editwin_set_xy_by_index(e, p - e->buff);
    807   }
    808 
    809   /* do we need to scroll down? */
    810   if (e->buffy - e->topline >= e->winlines) {
    811     e->topline += e->winlines / 2;
    812   }
     856  owl_editwin_point_move(e, 1);
    813857}
    814858
    815859void owl_editwin_move_to_nextword(owl_editwin *e)
    816860{
    817   int i, x;
    818   gunichar c = '\0';
    819 
    820861  /* if we're starting on a space, find the first non-space */
    821   i=_owl_editwin_get_index_from_xy(e);
    822   if (e->buff[i]==' ') {
    823     for (x=i; x<e->bufflen; x++) {
    824       if (e->buff[x]!=' ' && e->buff[x]!='\n') {
    825         _owl_editwin_set_xy_by_index(e, x);
    826         break;
    827       }
    828     }
    829   }
    830 
    831   /* find the next space, newline or end of line and go
    832      there, if already at the end of the line, continue on to the next */
    833   i=owl_editwin_get_numcells_on_line(e, e->buffy);
    834   c = _owl_editwin_get_char_at_xy(e);
    835   if (e->buffx < i) {
    836     /* move right till end of line */
    837     while (e->buffx < i) {
    838       owl_editwin_key_right(e);
    839       c = _owl_editwin_get_char_at_xy(e);
    840       if (c == ' ') return;
    841       if (e->buffx == i) return;
    842     }
    843   } else if (e->buffx == i) {
    844     /* try to move down */
    845     if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    846       if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    847         e->buffx=0;
    848         e->buffy++;
    849         owl_editwin_move_to_nextword(e);
    850       }
    851     }
    852   }
     862  owl_editwin_move_if_in(e, 1, WHITESPACE);
     863
     864  /* now find the end of this word */
     865  owl_editwin_move_if_not_in(e, 1, WHITESPACE);
    853866}
    854867
     
    857870void owl_editwin_move_to_previousword(owl_editwin *e)
    858871{
    859   int i;
    860   gunichar c;
    861   char *ptr1, *ptr2;
    862 
    863   /* are we already at the beginning of the word? */
    864   c = _owl_editwin_get_char_at_xy(e);
    865   i = _owl_editwin_get_index_from_xy(e);
    866   ptr1 = e->buff + i;
    867   if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
    868     ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
    869     c = g_utf8_get_char(ptr1);
    870     if (c == ' ' || c == '\n') {
    871       owl_editwin_key_left(e);     
    872     }
    873   }
    874 
    875   /* are we starting on a space character? */
    876   i = _owl_editwin_get_index_from_xy(e);
    877   while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
    878     /* find the first non-space */
    879     owl_editwin_key_left(e);     
    880     i = _owl_editwin_get_index_from_xy(e);
    881   }
    882 
    883   /* find the last non-space */
    884   ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    885   while (ptr1 >= e->buff + e->lock) {
    886     ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
    887     if (!ptr2) break;
    888    
    889     c = g_utf8_get_char(ptr2);
    890     if (c == ' ' || c == '\n'){
    891       break;
    892     }
    893     owl_editwin_key_left(e);
    894     ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    895   }
    896 }
    897 
     872  _owl_editwin_excursion x;
     873  int beginning;
     874  /* if in middle of word, beginning of word */
     875
     876  /* if at beginning of a word, find beginning of previous word */
     877
     878  if (_owl_editwin_is_char_in(e, WHITESPACE)) {
     879    /* if in whitespace past end of word, find a word , the find the beginning*/
     880    owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last
     881                                                    character of the word */
     882    owl_editwin_save_excursion(e, &x);
     883    /* are we at the beginning of a word? */
     884    owl_editwin_point_move(e, -1);
     885    beginning = _owl_editwin_is_char_in(e, WHITESPACE);
     886    owl_editwin_restore_excursion(e, &x);
     887    if (beginning)
     888      return;
     889   } else {
     890    /* in the middle of the word; */
     891    owl_editwin_save_excursion(e, &x);
     892    owl_editwin_point_move(e, -1);
     893    if (_owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */
     894      owl_editwin_move_to_previousword(e); /* previous case */
     895      return;
     896    } else {
     897      owl_editwin_restore_excursion(e, &x);
     898    }
     899  }
     900  owl_editwin_move_if_not_in(e, -1, WHITESPACE);
     901  /* will go past */
     902  if (e->index > e->lock)
     903    owl_editwin_point_move(e, 1);
     904}
    898905
    899906void owl_editwin_delete_nextword(owl_editwin *e)
    900907{
    901   char *ptr1, *start;
    902   gunichar c;
    903 
    904   if (e->bufflen==0) return;
    905 
    906   start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    907   /* if we start out on a space character then jump past all the
    908      spaces up first */
    909   while (*ptr1 == ' ' || *ptr1 == '\n') {
    910     ++ptr1;
    911   }
    912 
    913   /* then jump past the next word */
    914  
    915   while (ptr1 && ptr1 - e->buff < e->bufflen) {
    916     c = g_utf8_get_char(ptr1);
    917     if (c == ' ' || c == '\n' || c == '\0') break;
    918     ptr1 = g_utf8_find_next_char(ptr1, NULL);
    919   }
    920 
    921   if (ptr1) { /* We broke on a space, */
    922     ptr1 = g_utf8_find_next_char(ptr1, NULL);
    923     if (ptr1) { /* and there's a character after it, */
    924       /* nuke everything back to our starting point. */
    925       _owl_editwin_remove_bytes(e, ptr1 - start);
    926       return;
    927     }
    928   }
    929  
    930   /* If we get here, we ran out of string, drop what's left. */
    931   *start = '\0';
    932   e->bufflen = start - e->buff;
     908  _owl_editwin_excursion x;
     909  int end;
     910
     911  owl_editwin_save_excursion(e, &x);
     912  owl_editwin_move_to_nextword(e);
     913  end = e->index;
     914  owl_editwin_restore_excursion(e, &x);
     915  _owl_editwin_remove_bytes(e, end - e->index);
    933916}
    934917
     
    938921  int startpos, endpos;
    939922
    940   startpos = _owl_editwin_get_index_from_xy(e);
     923  startpos = e->index;
    941924  owl_editwin_move_to_previousword(e);
    942   endpos = _owl_editwin_get_index_from_xy(e);
     925  endpos = e->index;
    943926  _owl_editwin_remove_bytes(e, startpos-endpos);
    944927}
    945928
     929void owl_editwin_move_to_line_end(owl_editwin *e)
     930{
     931  owl_editwin_move_to_end_of_line(e);
     932}
     933
    946934void owl_editwin_delete_to_endofline(owl_editwin *e)
    947935{
    948   int i;
    949 
    950   if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
    951     /* normal line */
    952     i=_owl_editwin_get_index_from_xy(e);
    953     while(i < e->bufflen) {
    954       if (e->buff[i]!='\n') {
    955         owl_editwin_delete_char(e);
    956       } else if ((e->buff[i]=='\n') && (i==e->bufflen-1)) {
    957         owl_editwin_delete_char(e);
    958       } else {
    959         return;
    960       }
    961     }
    962   } else if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    963     /* line with cursor at the end but not on very last line */
    964     owl_editwin_key_right(e);
    965     owl_editwin_backspace(e);
    966   }
    967 }
    968 
    969 void owl_editwin_move_to_line_end(owl_editwin *e)
    970 {
    971   e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
     936  _owl_editwin_excursion x;
     937  int end;
     938
     939  owl_editwin_save_excursion(e, &x);
     940  owl_editwin_move_to_line_end(e);
     941  end = e->index;
     942  owl_editwin_restore_excursion(e, &x);
     943  _owl_editwin_remove_bytes(e, end - e->index);
    972944}
    973945
    974946void owl_editwin_move_to_line_start(owl_editwin *e)
    975947{
    976   e->buffx=0;
    977   owl_editwin_adjust_for_locktext(e);
     948  owl_editwin_move_to_beginning_of_line(e);
    978949}
    979950
    980951void owl_editwin_move_to_end(owl_editwin *e)
    981952{
    982   /* go to last char */
    983   e->buffy=owl_editwin_get_numlines(e)-1;
    984   e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    985   owl_editwin_key_right(e);
    986 
    987   /* do we need to scroll? */
    988   /*
    989   if (e->buffy-e->topline > e->winlines) {
    990     e->topline+=e->winlines/2;
    991   }
    992   */
    993   owl_editwin_recenter(e);
     953  e->index = e->bufflen;
    994954}
    995955
    996956void owl_editwin_move_to_top(owl_editwin *e)
    997957{
    998   _owl_editwin_set_xy_by_index(e, 0);
    999 
    1000   /* do we need to scroll? */
    1001   e->topline=0;
    1002 
    1003   owl_editwin_adjust_for_locktext(e);
     958  e->index = e->lock;
    1004959}
    1005960
    1006961void owl_editwin_fill_paragraph(owl_editwin *e)
    1007962{
     963#if 0 /* XXX */
     964  _owl_editwin_excursion x;
    1008965  int i, save;
    1009966
    1010967  /* save our starting point */
    1011   save=_owl_editwin_get_index_from_xy(e);
     968  owl_editwin_save_excursion(e, &x);
     969
     970  save = e->index;
    1012971
    1013972  /* scan back to the beginning of this paragraph */
     
    1015974    if ( (i<=e->lock) ||
    1016975         ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
    1017       _owl_editwin_set_xy_by_index(e, i+1);
     976      e->index = i + 1;
    1018977      break;
    1019978    }
     
    10411000      /* we may have added a character. */
    10421001      if (i < save) save += e->bufflen - len;
    1043       _owl_editwin_set_xy_by_index(e, i);
     1002      e->index = i;
    10441003    }
    10451004
     
    10721031
    10731032  /* put cursor back at starting point */
    1074   _owl_editwin_set_xy_by_index(e, save);
    1075 
    1076   /* do we need to scroll? */
    1077   if (e->buffy-e->topline < 0) {
    1078     e->topline-=e->winlines/2;
    1079   }
     1033  owl_editwin_restore_excursion(e, &x);
     1034#endif
    10801035}
    10811036
     
    10831038int owl_editwin_is_at_end(owl_editwin *e)
    10841039{
    1085   int cur=_owl_editwin_get_index_from_xy(e);
    1086   return (only_whitespace(e->buff+cur));
     1040  return (only_whitespace(e->buff + e->index));
    10871041}
    10881042
     
    11171071void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
    11181072{
    1119   /* check if we need to scroll down */
    1120   if (e->buffy-e->topline >= e->winlines) {
    1121     e->topline+=e->winlines/2;
    1122   }
     1073  /* XXX force a redisplay? */
    11231074  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
    11241075    owl_command_editmulti_done(e);
     
    11791130}
    11801131
    1181 int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
    1182 {
    1183   int i;
    1184   char *ptr1, *ptr2;
    1185   gunichar c;
    1186 
    1187   if (e->bufflen==0) return(0);
    1188  
    1189   /* first go to the yth line */
    1190   ptr1=e->buff;
    1191   for (i=0; i<line; i++) {
    1192     ptr2=strchr(ptr1, '\n');
    1193     if (!ptr2) {
    1194       /* we're already on the last line */
    1195       return(0);
    1196     }
    1197     ptr1=ptr2+1;
    1198   }
    1199 
    1200   /* now count cells */
    1201   i = 0;
    1202   ptr2 = ptr1;
    1203   while (ptr2 - e->buff < e->bufflen
    1204          && *ptr2 != '\n') {
    1205     c = g_utf8_get_char(ptr2);
    1206     i += mk_wcwidth(c);
    1207     ptr2 = g_utf8_next_char(ptr2);
    1208   }
    1209   return i;
    1210 }
    1211 
    12121132int owl_editwin_get_numlines(owl_editwin *e)
    12131133{
     
    12151135}
    12161136
     1137int owl_editwin_get_echochar(owl_editwin *e) {
     1138  return e->echochar;
     1139}
  • global.c

    rbd783db ra556caa  
    4747  g->rightshift=0;
    4848
    49   owl_editwin_init(&(g->tw), NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
     49  g->tw = owl_editwin_allocate();
     50  owl_editwin_init(g->tw, NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
    5051
    5152  owl_keyhandler_init(&g->kh);
     
    147148  g->typwin=newwin(typwin_lines, cols, g->recwinlines+2, 0);
    148149
    149   owl_editwin_set_curswin(&(g->tw), g->typwin, typwin_lines, g->cols);
     150  owl_editwin_set_curswin(g->tw, g->typwin, typwin_lines, g->cols);
    150151
    151152  idlok(g->typwin, FALSE);
     
    261262
    262263owl_editwin *owl_global_get_typwin(owl_global *g) {
    263   return(&(g->tw));
     264  return(g->tw);
    264265}
    265266
     
    478479  owl_mainwin_redisplay(&(g->mw));
    479480  sepbar(NULL);
    480   owl_editwin_redisplay(&(g->tw), 0);
     481  owl_editwin_redisplay(g->tw, 0);
    481482  owl_function_full_redisplay(&g);
    482483
  • owl.h

    rd5cc1c5d ra556caa  
    424424} owl_history;
    425425
    426 typedef struct _owl_editwin {
    427   char *buff;
    428   owl_history *hist;
    429   int bufflen;
    430   int allocated;
    431   int buffx, buffy;
    432   int topline;
    433   int winlines, wincols, fillcol, wrapcol;
    434   WINDOW *curswin;
    435   int style;
    436   int lock;
    437   int dotsend;
    438   int echochar;
    439 
    440   char *command;
    441   void (*callback)(struct _owl_editwin*);
    442   void *cbdata;
    443 } owl_editwin;
     426typedef struct _owl_editwin owl_editwin;
    444427
    445428typedef struct _owl_keybinding {
     
    556539  int config_format;
    557540  void *buffercbdata;
    558   owl_editwin tw;
     541  owl_editwin *tw;
    559542  owl_viewwin vw;
    560543  void *perl;
  • perlconfig.c

    rd1ae4a4 ra556caa  
    482482void owl_perlconfig_edit_callback(owl_editwin *e)
    483483{
    484   SV *cb = (SV*)(e->cbdata);
     484  SV *cb = (SV*)owl_editwin_get_cbdata(e);
    485485  SV *text;
    486486  dSP;
     
    509509
    510510  SvREFCNT_dec(cb);
    511   e->cbdata = NULL;
     511  owl_editwin_set_cbdata(e, NULL);
    512512}
    513513
Note: See TracChangeset for help on using the changeset viewer.