source: editwin.c @ cf83b7a

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since cf83b7a was cf83b7a, checked in by James M. Kretchmar <kretch@mit.edu>, 17 years ago
Started adding code to do question/response stuff
  • Property mode set to 100644
File size: 20.6 KB
Line 
1#include "owl.h"
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <ctype.h>
6
7static const char fileIdent[] = "$Id$";
8
9#define INCR 5000
10
11/* initialize the editwin e.
12 * 'win' is an already initialzed curses window that will be used by editwin
13 */
14void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
15{
16  e->buff=owl_malloc(INCR); 
17  e->buff[0]='\0';
18  e->bufflen=0;
19  e->hist=hist;
20  e->allocated=INCR;
21  e->buffx=0;
22  e->buffy=0;
23  e->topline=0;
24  e->winlines=winlines;
25  e->wincols=wincols;
26  e->fillcol=owl_editwin_limit_maxcols(wincols-1, owl_global_get_edit_maxfillcols(&g));
27  e->wrapcol=owl_editwin_limit_maxcols(wincols-1, owl_global_get_edit_maxwrapcols(&g));
28  e->curswin=win;
29  e->style=style;
30  if ((style!=OWL_EDITWIN_STYLE_MULTILINE) &&
31      (style!=OWL_EDITWIN_STYLE_ONELINE)) {
32    e->style=OWL_EDITWIN_STYLE_MULTILINE;
33  }
34  e->lock=0;
35  e->dotsend=0;
36  e->echochar='\0';
37  if (win) werase(win);
38}
39
40void owl_editwin_set_curswin(owl_editwin *e, WINDOW *w, int winlines, int wincols)
41{
42  e->curswin=w;
43  e->winlines=winlines;
44  e->wincols=wincols;
45  e->fillcol=owl_editwin_limit_maxcols(wincols-1, owl_global_get_edit_maxfillcols(&g));
46  e->wrapcol=owl_editwin_limit_maxcols(wincols-1, owl_global_get_edit_maxwrapcols(&g));
47}
48
49/* echo the character 'ch' for each normal character keystroke,
50 * excepting locktext.  This is useful for entering passwords etc.  If
51 * ch=='\0' characters are echo'd normally
52 */
53void owl_editwin_set_echochar(owl_editwin *e, int ch)
54{
55  e->echochar=ch;
56}
57
58WINDOW *owl_editwin_get_curswin(owl_editwin *e)
59{
60  return(e->curswin);
61}
62
63void owl_editwin_set_history(owl_editwin *e, owl_history *h)
64{
65  e->hist=h;
66}
67
68owl_history *owl_editwin_get_history(owl_editwin *e)
69{
70  return(e->hist);
71}
72
73void owl_editwin_set_dotsend(owl_editwin *e)
74{
75  e->dotsend=1;
76}
77
78int owl_editwin_limit_maxcols(int v, int maxv)
79{
80  if (maxv > 5 && v > maxv) {
81    return(maxv);
82  } else {
83    return(v);
84  }
85}
86
87/* set text to be 'locked in' at the beginning of the buffer, any
88 * previous text (including locked text) will be overwritten
89 */
90void owl_editwin_set_locktext(owl_editwin *e, char *text)
91{
92 
93  int x, y;
94
95  x=e->buffx;
96  y=e->buffy;
97  e->buffx=0;
98  e->buffy=0;
99  owl_editwin_overwrite_string(e, text);
100  e->lock=strlen(text);
101  /* if (text[e->lock-1]=='\n') e->lock--; */
102  e->buffx=x;
103  e->buffy=y;
104  owl_editwin_adjust_for_locktext(e);
105  owl_editwin_redisplay(e, 0);
106}
107
108int owl_editwin_get_style(owl_editwin *e)
109{
110  return(e->style);
111}
112
113void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h)
114{
115  char *ptr;
116
117  owl_editwin_set_history(e, h);
118  if (e->style==newstyle) return;
119
120  if (newstyle==OWL_EDITWIN_STYLE_MULTILINE) {
121    e->style=newstyle;
122  } else if (newstyle==OWL_EDITWIN_STYLE_ONELINE) {
123    e->style=newstyle;
124
125    /* nuke everything after the first line */
126    if (e->bufflen > 0) {
127      ptr=strchr(e->buff, '\n')-1;
128      if (ptr) {
129        e->bufflen=ptr - e->buff;
130        e->buff[e->bufflen]='\0';
131        e->buffx=0;
132        e->buffy=0;
133      }
134    }
135  }
136}
137
138/* completly reinitialize the buffer */
139void owl_editwin_fullclear(owl_editwin *e)
140{
141  owl_free(e->buff);
142  owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
143}
144
145/* clear all text except for locktext and put the cursor at the
146 * beginning
147 */
148void owl_editwin_clear(owl_editwin *e)
149{
150
151  int lock;
152  int dotsend=e->dotsend;
153  char *locktext=NULL;
154
155  lock=0;
156  if (e->lock > 0) {
157    lock=1;
158
159    locktext=owl_malloc(e->lock+20);
160    strncpy(locktext, e->buff, e->lock);
161    locktext[e->lock]='\0';
162  }
163
164  owl_free(e->buff);
165  owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
166
167  if (lock > 0) {
168    owl_editwin_set_locktext(e, locktext);
169  }
170  if (dotsend) {
171    owl_editwin_set_dotsend(e);
172  }
173
174  if (locktext) owl_free(locktext);
175  owl_editwin_adjust_for_locktext(e);
176}
177
178
179/* malloc more space for the buffer */
180void _owl_editwin_addspace(owl_editwin *e)
181{
182  e->buff=owl_realloc(e->buff, e->allocated+INCR);
183  if (!e->buff) {
184    /* error */
185    return;
186  }
187  e->allocated+=INCR;
188}
189
190void owl_editwin_recenter(owl_editwin *e)
191{
192  e->topline=e->buffy-(e->winlines/2);
193  if (e->topline<0) e->topline=0;
194  if (e->topline>owl_editwin_get_numlines(e)) e->topline=owl_editwin_get_numlines(e);
195}
196
197/* regenerate the text on the curses window */
198/* if update == 1 then do a doupdate(), otherwise do not */
199void owl_editwin_redisplay(owl_editwin *e, int update)
200{
201 
202  char *ptr1, *ptr2, *ptr3, *buff;
203  int i;
204
205  werase(e->curswin);
206  wmove(e->curswin, 0, 0);
207
208  /* start at topline */
209  ptr1=e->buff;
210  for (i=0; i<e->topline; i++) {
211    ptr2=strchr(ptr1, '\n');
212    if (!ptr2) {
213      /* we're already on the last line */
214      break;
215    }
216    ptr1=ptr2+1;
217  }
218  /* ptr1 now stores the starting point */
219
220  /* find the ending point and store it in ptr3 */
221  ptr2=ptr1;
222  ptr3=ptr1;
223  for (i=0; i<e->winlines; i++) {
224    ptr3=strchr(ptr2, '\n');
225    if (!ptr3) {
226      /* we've hit the last line */
227      /* print everything to the end */
228      ptr3=e->buff+e->bufflen-1;
229      ptr3--;
230      break;
231    }
232    ptr2=ptr3+1;
233  }
234  ptr3+=2;
235
236  buff=owl_malloc(ptr3-ptr1+50);
237  strncpy(buff, ptr1, ptr3-ptr1);
238  buff[ptr3-ptr1]='\0';
239  if (e->echochar=='\0') {
240    waddstr(e->curswin, buff);
241  } else {
242    /* translate to echochar, *except* for the locktext */
243    int len;
244    int dolocklen=e->lock-(ptr1-e->buff);
245
246    for (i=0; i<dolocklen; i++) {
247      waddch(e->curswin, buff[i]);
248    }
249    len=strlen(buff);
250    for (i=0; i<len-dolocklen; i++) {
251      waddch(e->curswin, e->echochar);
252    }
253  }
254  wmove(e->curswin, e->buffy-e->topline, e->buffx);
255  wnoutrefresh(e->curswin);
256  if (update==1) {
257    doupdate();
258  }
259  owl_free(buff);
260}
261
262
263/* linewrap the word just before the cursor.
264 * returns 0 on success
265 * returns -1 if we could not wrap.
266 */
267int _owl_editwin_linewrap_word(owl_editwin *e)
268{
269  int i, z;
270
271  z=_owl_editwin_get_index_from_xy(e);
272  /* move back and line wrap the previous word */
273  for (i=z-1; ; i--) {
274    /* move back until you find a space or hit the beginning of the line */
275    if (e->buff[i]==' ') {
276      /* replace the space with a newline */
277      e->buff[i]='\n';
278      e->buffy++;
279      e->buffx=z-i-1;
280      /* were we on the last line */
281      return(0);
282    } else if (e->buff[i]=='\n' || i<=e->lock) {
283      /* we hit the begginning of the line or the buffer, we cannot
284       * wrap.
285       */
286      return(-1);
287    }
288  }
289}
290
291/* insert a character at the current point (shift later
292 * characters over)
293 */
294void owl_editwin_insert_char(owl_editwin *e, char c)
295{
296 
297  int z, i, ret;
298
299  /* \r is \n */
300  if (c=='\r') {
301    c='\n';
302  }
303
304  if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
305    /* perhaps later this will change some state that allows the string
306       to be read */
307    return;
308  }
309
310  /* make sure there is enough memory for the new text */
311  if ((e->bufflen+1) > (e->allocated-5)) {
312    _owl_editwin_addspace(e);
313  }
314
315  /* get the insertion point */
316  z=_owl_editwin_get_index_from_xy(e);
317
318  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
319  if ((e->buffx+1==e->wrapcol) && (c!='\n')) {
320    ret=_owl_editwin_linewrap_word(e);
321    if (ret==-1) {
322      /* we couldn't wrap, insert a hard newline instead */
323      owl_editwin_insert_char(e, '\n');
324    }
325  }
326
327  z=_owl_editwin_get_index_from_xy(e);
328  /* shift all the other characters right */
329  for (i=e->bufflen; i>z; i--) {
330    e->buff[i]=e->buff[i-1];
331  }
332
333  /* insert the new one */
334  e->buff[z]=c;
335
336  /* housekeeping */
337  e->bufflen++;
338  e->buff[e->bufflen]='\0';
339
340  /* advance the cursor */
341  if (c=='\n') {
342    e->buffx=0;
343    e->buffy++;
344  } else {
345    e->buffx++;
346  }
347}
348
349/* overwrite the character at the current point with 'c' */
350void owl_editwin_overwrite_char(owl_editwin *e, char c)
351{
352  int z;
353 
354  /* \r is \n */
355  if (c=='\r') {
356    c='\n';
357  }
358
359  if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
360    /* perhaps later this will change some state that allows the string
361       to be read */
362    return;
363  }
364
365  z=_owl_editwin_get_index_from_xy(e);
366
367  /* only if we are at the end of the buffer do we create new space */
368  if (z==e->bufflen) {
369    if ((e->bufflen+1) > (e->allocated-5)) {
370      _owl_editwin_addspace(e);
371    }
372  }
373 
374  e->buff[z]=c;
375
376  /* housekeeping if we are at the end of the buffer */
377  if (z==e->bufflen) {
378    e->bufflen++;
379    e->buff[e->bufflen]='\0';
380  }
381
382  /* advance the cursor */
383  if (c=='\n') {
384    e->buffx=0;
385    e->buffy++;
386  } else {
387    e->buffx++;
388  }
389
390}
391
392/* delete the character at the current point, following chars
393 * shift left.
394 */ 
395void owl_editwin_delete_char(owl_editwin *e)
396{
397  int z, i;
398
399  if (e->bufflen==0) return;
400 
401  /* get the deletion point */
402  z=_owl_editwin_get_index_from_xy(e);
403
404  if (z==e->bufflen) return;
405
406  for (i=z; i<e->bufflen; i++) {
407    e->buff[i]=e->buff[i+1];
408  }
409  e->bufflen--;
410  e->buff[e->bufflen]='\0';
411}
412
413/* Swap the character at point with the character at point-1 and
414 * advance the pointer.  If point is at beginning of buffer do
415 * nothing.  If point is after the last character swap point-1 with
416 * point-2.  (Behaves as observed in tcsh and emacs). 
417 */
418void owl_editwin_transpose_chars(owl_editwin *e)
419{
420  int z;
421  char tmp;
422
423  if (e->bufflen==0) return;
424 
425  /* get the cursor point */
426  z=_owl_editwin_get_index_from_xy(e);
427
428  if (z==e->bufflen) {
429    /* point is after last character */
430    z--;
431  } 
432
433  if (z-1 < e->lock) {
434    /* point is at beginning of buffer, do nothing */
435    return;
436  }
437
438  tmp=e->buff[z];
439  e->buff[z]=e->buff[z-1];
440  e->buff[z-1]=tmp;
441  owl_editwin_key_right(e);
442}
443
444/* insert 'string' at the current point, later text is shifted
445 * right
446 */
447void owl_editwin_insert_string(owl_editwin *e, char *string)
448{
449  int i, j;
450
451  j=strlen(string);
452  for (i=0; i<j; i++) {
453    owl_editwin_insert_char(e, string[i]);
454  }
455}
456
457/* write 'string' at the current point, overwriting text that is
458 * already there
459 */
460
461void owl_editwin_overwrite_string(owl_editwin *e, char *string)
462{
463  int i, j;
464
465  j=strlen(string);
466  for (i=0; i<j; i++) {
467    owl_editwin_overwrite_char(e, string[i]);
468  }
469}
470
471/* get the index into e->buff for the current cursor
472 * position.
473 */
474int _owl_editwin_get_index_from_xy(owl_editwin *e)
475{
476  int i;
477  char *ptr1, *ptr2;
478
479  if (e->bufflen==0) return(0);
480 
481  /* first go to the yth line */
482  ptr1=e->buff;
483  for (i=0; i<e->buffy; i++) {
484    ptr2=strchr(ptr1, '\n');
485    if (!ptr2) {
486      /* we're already on the last line */
487      break;
488    }
489    ptr1=ptr2+1;
490  }
491
492  /* now go to the xth character */
493  ptr2=strchr(ptr1, '\n');
494  if (!ptr2) {
495    ptr2=e->buff+e->bufflen;
496  }
497
498  if ((ptr2-ptr1) < e->buffx) {
499    ptr1=ptr2-1;
500  } else {
501    ptr1+=e->buffx;
502  }
503
504  /* printf("DEBUG: index is %i\r\n", ptr1-e->buff); */
505  return(ptr1-e->buff);
506}
507
508void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
509{
510  int z, i;
511
512  z=_owl_editwin_get_index_from_xy(e);
513  if (index>z) {
514    for (i=0; i<index-z; i++) {
515      owl_editwin_key_right(e);
516    }
517  } else if (index<z) {
518    for (i=0; i<z-index; i++) {
519      owl_editwin_key_left(e);
520    }
521  }
522}
523
524void owl_editwin_adjust_for_locktext(owl_editwin *e)
525{
526  /* if we happen to have the cursor over locked text
527   * move it to be out of the locktext region */
528  if (_owl_editwin_get_index_from_xy(e)<e->lock) {
529    _owl_editwin_set_xy_by_index(e, e->lock);
530  }
531}
532
533void owl_editwin_backspace(owl_editwin *e)
534{
535  /* delete the char before the current one
536   * and shift later chars left
537   */
538  if (_owl_editwin_get_index_from_xy(e) > e->lock) {
539    owl_editwin_key_left(e);
540    owl_editwin_delete_char(e);
541  }
542  owl_editwin_adjust_for_locktext(e);
543}
544
545void owl_editwin_key_up(owl_editwin *e)
546{
547  if (e->buffy > 0) e->buffy--;
548  if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
549    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
550  }
551
552  /* do we need to scroll? */
553  if (e->buffy-e->topline < 0) {
554    e->topline-=e->winlines/2;
555  }
556
557  owl_editwin_adjust_for_locktext(e);
558}
559
560void owl_editwin_key_down(owl_editwin *e)
561{
562  /* move down if we can */
563  if (e->buffy+1 < owl_editwin_get_numlines(e)) e->buffy++;
564
565  /* if we're past the last character move back */
566  if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
567    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
568  }
569
570  /* do we need to scroll? */
571  if (e->buffy-e->topline > e->winlines) {
572    e->topline+=e->winlines/2;
573  }
574
575  /* adjust for locktext */
576  owl_editwin_adjust_for_locktext(e);
577}
578
579void owl_editwin_key_left(owl_editwin *e)
580{
581  /* move left if we can, and maybe up a line */
582  if (e->buffx>0) {
583    e->buffx--;
584  } else if (e->buffy>0) {
585    e->buffy--;
586    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
587  }
588
589  /* do we need to scroll up? */
590  if (e->buffy-e->topline < 0) {
591    e->topline-=e->winlines/2;
592  }
593
594  /* make sure to avoid locktext */
595  owl_editwin_adjust_for_locktext(e);
596}
597
598void owl_editwin_key_right(owl_editwin *e)
599{
600  int i;
601
602  /* move right if we can, and skip down a line if needed */
603  i=owl_editwin_get_numchars_on_line(e, e->buffy);
604  if (e->buffx < i) {
605    e->buffx++;
606    /*  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) { */
607  } else if (_owl_editwin_get_index_from_xy(e) < e->bufflen) {
608    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
609      e->buffx=0;
610      e->buffy++;
611    }
612  }
613
614  /* do we need to scroll down? */
615  if (e->buffy-e->topline >= e->winlines) {
616    e->topline+=e->winlines/2;
617  }
618}
619
620void owl_editwin_move_to_nextword(owl_editwin *e)
621{
622  int i, x;
623
624  /* if we're starting on a space, find the first non-space */
625  i=_owl_editwin_get_index_from_xy(e);
626  if (e->buff[i]==' ') {
627    for (x=i; x<e->bufflen; x++) {
628      if (e->buff[x]!=' ' && e->buff[x]!='\n') {
629        _owl_editwin_set_xy_by_index(e, x);
630        break;
631      }
632    }
633  }
634
635  /* find the next space, newline or end of line and go there, if
636     already at the end of the line, continue on to the next */
637  i=owl_editwin_get_numchars_on_line(e, e->buffy);
638  if (e->buffx < i) {
639    /* move right till end of line */
640    while (e->buffx < i) {
641      e->buffx++;
642      if (e->buff[_owl_editwin_get_index_from_xy(e)]==' ') return;
643      if (e->buffx == i) return;
644    }
645  } else if (e->buffx == i) {
646    /* try to move down */
647    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
648      if (e->buffy+1 <  owl_editwin_get_numlines(e)) {
649        e->buffx=0;
650        e->buffy++;
651        owl_editwin_move_to_nextword(e);
652      }
653    }
654  }
655}
656
657/* go backwards to the last non-space character
658 */
659void owl_editwin_move_to_previousword(owl_editwin *e)
660{
661  int i, x;
662
663  /* are we already at the beginning of the word? */
664  i=_owl_editwin_get_index_from_xy(e);
665  if ( (e->buff[i]!=' ' && e->buff[i]!='\n' && e->buff[i]!='\0') &&
666       (e->buff[i-1]==' ' || e->buff[i-1]=='\n') ) {
667    owl_editwin_key_left(e);
668  }
669   
670  /* are we starting on a space character? */
671  i=_owl_editwin_get_index_from_xy(e);
672  if (e->buff[i]==' ' || e->buff[i]=='\n' || e->buff[i]=='\0') {
673    /* find the first non-space */
674    for (x=i; x>=e->lock; x--) {
675      if (e->buff[x]!=' ' && e->buff[x]!='\n' && e->buff[x]!='\0') {
676        _owl_editwin_set_xy_by_index(e, x);
677        break;
678      }
679    }
680  }
681
682  /* find the last non-space */
683  i=_owl_editwin_get_index_from_xy(e);
684  for (x=i; x>=e->lock; x--) {
685    if (e->buff[x-1]==' ' || e->buff[x-1]=='\n') {
686      _owl_editwin_set_xy_by_index(e, x);
687      break;
688    }
689  }
690  _owl_editwin_set_xy_by_index(e, x);
691}
692
693
694void owl_editwin_delete_nextword(owl_editwin *e)
695{
696  int z;
697
698  if (e->bufflen==0) return;
699
700  /* if we start out on a space character then gobble all the spaces
701     up first */
702  while (1) {
703    z=_owl_editwin_get_index_from_xy(e);
704    if (e->buff[z]==' ' || e->buff[z]=='\n') {
705      owl_editwin_delete_char(e);
706    } else {
707      break;
708    }
709  }
710
711  /* then nuke the next word */
712  while (1) {
713    z=_owl_editwin_get_index_from_xy(e);
714    if (e->buff[z+1]==' ' || e->buff[z+1]=='\n' || e->buff[z+1]=='\0') break;
715    owl_editwin_delete_char(e);
716  }
717  owl_editwin_delete_char(e);
718}
719
720void owl_editwin_delete_previousword(owl_editwin *e)
721{
722  /* go backwards to the last non-space character, then delete chars */
723  int i, startpos, endpos;
724
725  startpos = _owl_editwin_get_index_from_xy(e);
726  owl_editwin_move_to_previousword(e);
727  endpos = _owl_editwin_get_index_from_xy(e);
728  for (i=0; i<startpos-endpos; i++) {
729    owl_editwin_delete_char(e);
730  }
731}
732
733void owl_editwin_delete_to_endofline(owl_editwin *e)
734{
735  int i;
736
737  if (owl_editwin_get_numchars_on_line(e, e->buffy)>e->buffx) {
738    /* normal line */
739    i=_owl_editwin_get_index_from_xy(e);
740    while(i < e->bufflen) {
741      if (e->buff[i]!='\n') {
742        owl_editwin_delete_char(e);
743      } else if ((e->buff[i]=='\n') && (i==e->bufflen-1)) {
744        owl_editwin_delete_char(e);
745      } else {
746        return;
747      }
748    }
749  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) {
750    /* line with cursor at the end but not on very last line */
751    owl_editwin_key_right(e);
752    owl_editwin_backspace(e);
753  }
754}
755
756void owl_editwin_move_to_line_end(owl_editwin *e)
757{
758  e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
759}
760
761void owl_editwin_move_to_line_start(owl_editwin *e)
762{
763  e->buffx=0;
764  owl_editwin_adjust_for_locktext(e);
765}
766
767void owl_editwin_move_to_end(owl_editwin *e)
768{
769  /* go to last char */
770  e->buffy=owl_editwin_get_numlines(e)-1;
771  e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
772  owl_editwin_key_right(e);
773
774  /* do we need to scroll? */
775  if (e->buffy-e->topline > e->winlines) {
776    e->topline+=e->winlines/2;
777  }
778}
779
780void owl_editwin_move_to_top(owl_editwin *e)
781{
782  _owl_editwin_set_xy_by_index(e, 0);
783
784  /* do we need to scroll? */
785  e->topline=0;
786
787  owl_editwin_adjust_for_locktext(e);
788}
789
790void owl_editwin_fill_paragraph(owl_editwin *e)
791{
792  int i, save;
793
794  /* save our starting point */
795  save=_owl_editwin_get_index_from_xy(e);
796
797  /* scan back to the beginning of this paragraph */
798  for (i=save; i>=e->lock; i--) {
799    if ( (i<=e->lock) ||
800         ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
801      _owl_editwin_set_xy_by_index(e, i+1);
802      break;
803    }
804  }
805
806  /* main loop */
807  while (1) {
808    i=_owl_editwin_get_index_from_xy(e);
809
810    /* bail if we hit the end of the buffer */
811    if (i>=e->bufflen) break;
812
813    /* bail if we hit the end of the paragraph */
814    if (e->buff[i]=='\n' && e->buff[i+1]=='\n') break;
815
816    /* if we've travelled too far, linewrap */
817    if ((e->buffx) >= e->fillcol) {
818      _owl_editwin_linewrap_word(e);
819    }
820
821    /* did we hit the end of a line too soon? */
822    i=_owl_editwin_get_index_from_xy(e);
823    if (e->buff[i]=='\n' && e->buffx<e->fillcol-1) {
824      /* ********* we need to make sure we don't pull in a word that's too long ***********/
825      e->buff[i]=' ';
826    }
827   
828    /* fix spacing */
829    i=_owl_editwin_get_index_from_xy(e);
830    if (e->buff[i]==' ' && e->buff[i+1]==' ') {
831      if (e->buff[i-1]=='.' || e->buff[i-1]=='!' || e->buff[i-1]=='?') {
832        owl_editwin_key_right(e);
833      } else {
834        owl_editwin_delete_char(e);
835        /* if we did this ahead of the save point, adjust it */
836        if (i<save) save--;
837      }
838    } else {
839      owl_editwin_key_right(e);
840    }
841
842  }
843
844  /* put cursor back at starting point */
845  _owl_editwin_set_xy_by_index(e, save);
846
847  /* do we need to scroll? */
848  if (e->buffy-e->topline < 0) {
849    e->topline-=e->winlines/2;
850  }
851}
852
853/* returns true if only whitespace remains */
854int owl_editwin_is_at_end(owl_editwin *e)
855{
856  int cur=_owl_editwin_get_index_from_xy(e);
857  return (only_whitespace(e->buff+cur));
858}
859
860int owl_editwin_check_dotsend(owl_editwin *e)
861{
862  int i;
863
864  if (!e->dotsend) return(0);
865  for (i=e->bufflen-1; i>0; i--) {
866    if (e->buff[i] == '.' 
867        && (e->buff[i-1] == '\n' || e->buff[i-1] == '\r')
868        && (e->buff[i+1] == '\n' || e->buff[i+1] == '\r')) {
869      e->bufflen = i;
870      e->buff[i] = '\0';
871      return(1);
872    }
873    if (!isspace((int) e->buff[i])) {
874      return(0);
875    }
876  }
877  return(0);
878}
879
880void owl_editwin_post_process_char(owl_editwin *e, int j)
881{
882  /* check if we need to scroll down */
883  if (e->buffy-e->topline >= e->winlines) {
884    e->topline+=e->winlines/2;
885  }
886  if ((j==13 || j==10) && owl_editwin_check_dotsend(e)) {
887    owl_command_editmulti_done(e);
888    return;
889  }
890  owl_editwin_redisplay(e, 0); 
891}
892
893void owl_editwin_process_char(owl_editwin *e, int j)
894{
895  if (j == ERR) return;
896  if (j>127 || ((j<32) && (j!=10) && (j!=13))) {
897    return;
898  } else {
899    owl_editwin_insert_char(e, j);
900  }
901}
902
903char *owl_editwin_get_text(owl_editwin *e)
904{
905  return(e->buff+e->lock);
906}
907
908int owl_editwin_get_numchars_on_line(owl_editwin *e, int line)
909{
910  int i;
911  char *ptr1, *ptr2;
912
913  if (e->bufflen==0) return(0);
914 
915  /* first go to the yth line */
916  ptr1=e->buff;
917  for (i=0; i<line; i++) {
918    ptr2=strchr(ptr1, '\n');
919    if (!ptr2) {
920      /* we're already on the last line */
921      return(0);
922    }
923    ptr1=ptr2+1;
924  }
925
926  /* now go to the xth character */
927  ptr2=strchr(ptr1, '\n');
928  if (!ptr2) {
929    return(e->buff + e->bufflen - ptr1);
930  }
931  return(ptr2-ptr1); /* don't count the newline for now */
932}
933
934int owl_editwin_get_numlines(owl_editwin *e)
935{
936  return(owl_text_num_lines(e->buff));
937}
938
Note: See TracBrowser for help on using the repository browser.