Changeset ebf0128


Ignore:
Timestamp:
Jul 11, 2009, 1:14:34 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:
2f21a41
Parents:
7d25006
git-author:
Karl Ramm <kcr@1ts.org> (06/11/09 11:18:42)
git-committer:
Nelson Elhage <nelhage@mit.edu> (07/11/09 13:14:34)
Message:
some line-wrap infrastructure + refactoring

Keep track of excursions and fix them up when replace needs to
Keep track of the current cursor x for word wrapping convenience
minor refactor owl_editwin_init v. owl_editwin_set_curswin
factor oe_char_width out of oe_find_display_line
factor oe_insert_char back out of owl_editwin_process_char
explicatory comment in owl_editwin_limit_maxcols
File:
1 edited

Legend:

Unmodified
Added
Removed
  • editwin.c

    r7d25006 rebf0128  
    66
    77static const char fileIdent[] = "$Id$";
     8
     9#define VALID_EXCURSION (0x9a2b4729)
     10
     11typedef struct oe_excursion_struct { /*noproto*/
     12  int valid;
     13  int index;
     14  int goal_column;
     15  int lock;
     16  struct oe_excursion_struct *next;
     17} oe_excursion;
    818
    919struct _owl_editwin { /*noproto*/
     
    1525  int goal_column;
    1626  int topindex;
     27  int cursorx;
    1728  int winlines, wincols, fillcol, wrapcol;
    1829  WINDOW *curswin;
     
    2132  int dotsend;
    2233  int echochar;
     34  oe_excursion *excursions;
    2335
    2436  char *command;
     
    2739};
    2840
    29 typedef struct { /*noproto*/
    30   int index;
    31   int goal_column;
    32   int lock;
    33 } oe_excursion;
    3441
    3542static void oe_reframe(owl_editwin *e);
    3643static void oe_save_excursion(owl_editwin *e, oe_excursion *x);
     44static void oe_release_excursion(owl_editwin *e, oe_excursion *x);
    3745static void oe_restore_excursion(owl_editwin *e, oe_excursion *x);
     46static int oe_count_glyphs(char *s);
     47static int oe_char_width(gunichar c, int column);
    3848static int oe_find_display_line(owl_editwin *e, int *x, int index);
     49static void oe_insert_char(owl_editwin *e, gunichar c);
    3950static int owl_editwin_limit_maxcols(int v, int maxv);
    4051static int owl_editwin_check_dotsend(owl_editwin *e);
    4152static int owl_editwin_is_char_in(owl_editwin *e, char *set);
    4253static gunichar owl_editwin_get_char_at_point(owl_editwin *e);
    43 static void owl_editwin_replace(owl_editwin *e, int count, char *s);
    44 static int oe_count_glyphs(char *s);
     54static int owl_editwin_replace(owl_editwin *e, int count, char *s);
    4555
    4656#define INCR 4096
     
    6777static inline void oe_set_index(owl_editwin *e, int index)
    6878{
     79  if (index != e->index) {
     80    e->goal_column = -1;
     81    e->cursorx = -1;
     82  }
    6983  e->index = index;
    70   e->goal_column = -1;
    7184}
    7285
     
    8396  oe_set_index(e, 0);
    8497  e->goal_column = -1;
    85   e->topindex=0;
    86   e->winlines=winlines;
    87   e->wincols=wincols;
    88   e->fillcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxfillcols(&g));
    89   e->wrapcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxwrapcols(&g));
    90   e->curswin=win;
     98  e->cursorx = -1;
     99  e->topindex = 0;
     100  e->excursions = NULL;
     101  owl_editwin_set_curswin(e, win, winlines, wincols);
    91102  e->style=style;
    92103  if ((style!=OWL_EDITWIN_STYLE_MULTILINE) &&
     
    185196static int owl_editwin_limit_maxcols(int v, int maxv)
    186197{
     198  /* maxv > 5 ? MAX(v, vax) : v */
    187199  if (maxv > 5 && v > maxv) {
    188200    return(maxv);
     
    282294  x->goal_column = e->goal_column;
    283295  x->lock = e->lock;
     296
     297  x->valid = VALID_EXCURSION;
     298  x->next = e->excursions;
     299  e->excursions = x;
     300}
     301
     302static void oe_release_excursion(owl_editwin *e, oe_excursion *x)
     303{
     304  oe_excursion *p;
     305
     306  x->valid = 0;
     307  if (e->excursions == NULL)
     308    /* XXX huh. */ ;
     309  else if (e->excursions == x)
     310    e->excursions = x->next;
     311  else {
     312    for (p = e->excursions; p->next != NULL; p = p->next)
     313      if (p->next == x) {
     314        p->next = p->next->next;
     315        break;
     316      }
     317    /* and if we ran off the end? XXX */
     318  }
    284319}
    285320
    286321static void oe_restore_excursion(owl_editwin *e, oe_excursion *x)
    287322{
    288   oe_set_index(e, x->index);
    289   e->goal_column = x->goal_column;
    290   e->lock = x->lock;
     323  if (x->valid == VALID_EXCURSION) {
     324    oe_set_index(e, x->index);
     325    e->goal_column = x->goal_column;
     326    e->lock = x->lock;
     327
     328    oe_release_excursion(e, x);
     329  }
    291330}
    292331
     
    316355}
    317356
     357static int oe_char_width(gunichar c, int column)
     358{
     359  int cw;
     360
     361  if (c == 9) /* TAB */
     362    return TABSIZE - column % TABSIZE;
     363
     364  cw = mk_wcwidth(c);
     365
     366  if (cw < 0) /* control characters */
     367    cw = 0;
     368
     369  return cw;
     370}
     371
    318372static int oe_find_display_line(owl_editwin *e, int *x, int index)
    319373{
    320374  int width = 0, cw;
    321   gunichar c = -1;
     375  gunichar c;
    322376  char *p;
    323377
     
    331385
    332386    /* figure out how wide it is */
    333     if (c == 9) /* TAB */
    334       cw = TABSIZE - width % TABSIZE;
    335     else
    336       cw = mk_wcwidth(c);
    337     if (cw < 0) /* control characters */
    338         cw = 0;
     387    cw = oe_char_width(c, width);
    339388
    340389    if (width + cw > e->wincols) {
     
    434483
    435484  wmove(e->curswin, y, x);
     485  e->cursorx = x;
     486
    436487  wnoutrefresh(e->curswin);
    437488  if (update == 1)
     
    439490}
    440491
    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;
     492/* replace count characters at the point with s, returning the change in size */
     493static int owl_editwin_replace(owl_editwin *e, int replace, char *s)
     494{
     495  int start, end, i, free, need, size, change;
    444496  char *p;
     497  oe_excursion *x;
    445498
    446499  if (!g_utf8_validate(s, -1, NULL)) {
    447500    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
    448     return;
     501    return 0;
    449502  }
    450503
     
    465518    if (p == NULL) {
    466519      /* XXX signal impending doom somehow and don't do anything */
    467       return;
     520      return 0;
    468521    }
    469522    e->buff = p;
     
    473526  memmove(e->buff + start + strlen(s), e->buff + end, e->bufflen + 1 - end);
    474527  memcpy(e->buff + start, s, strlen(s));
    475   e->bufflen += start - end + strlen(s);
     528  change = start - end + strlen(s);
     529  e->bufflen += change;
    476530  e->index += strlen(s);
     531
     532  /* fix up any saved points after the replaced area */
     533  for (x = e->excursions; x != NULL; x = x->next)
     534    if (x->index > start) {
     535      if (x->index < end)
     536        x->index = end;
     537      else
     538        x->index += change;
     539    }
     540
     541  return change;
    477542}
    478543
     
    9771042}
    9781043
     1044static void oe_insert_char(owl_editwin *e, gunichar c)
     1045{
     1046  char tmp[7];
     1047
     1048  if (c == '\r') /* translate CRs to NLs */
     1049    c = '\n';
     1050
     1051  if (!g_unichar_iscntrl(c) || c == '\n' || c== '\n' ) {
     1052    memset(tmp, 0, 7);
     1053
     1054    if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
     1055      return;
     1056    }
     1057
     1058    g_unichar_to_utf8(c, tmp);
     1059    owl_editwin_replace(e, 0, tmp);
     1060  }
     1061}
     1062
    9791063void owl_editwin_process_char(owl_editwin *e, owl_input j)
    9801064{
    981   char tmp[7];
    982 
    9831065  if (j.ch == ERR)
    9841066    return;
    9851067  /* Ignore ncurses control characters. */
    9861068  if (j.ch < 0x100) {
    987     if (!(g_unichar_iscntrl(j.uch) && (j.uch != 10) && (j.uch != 13)) || j.uch==9 ) {
    988       memset(tmp, 0, 7);
    989 
    990       /* \r is \n */
    991       if (j.uch == '\r') {
    992         j.uch = '\n';
    993       }
    994 
    995       if (j.uch == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    996         return;
    997       }
    998 
    999       g_unichar_to_utf8(j.uch, tmp);
    1000       owl_editwin_replace(e, 0, tmp);
    1001     }
     1069    oe_insert_char(e, j.uch);
    10021070  }
    10031071}
Note: See TracChangeset for help on using the changeset viewer.