source: editwin.c @ 10b866d

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