source: editwin.c @ cc6f009

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