source: editwin.c @ 4c46dfd

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