source: editwin.c @ c9334b1

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