Renamed package to ion1, and made it conflict with package 'ion'.
[ion1.git] / src / edln.c
blob562e04703a3d39f886a7a1304d6ae2f8bf59262e
1 /*
2 * ion/edln.c
4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 * See the included file LICENSE for details.
6 */
8 #include <string.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include "common.h"
13 #include "selection.h"
14 #include "edln.h"
15 #include "wedln.h"
16 #include "complete.h"
18 #define EDLN_ALLOCUNIT 16
19 #define EDLN_HISTORY_SIZE 256
22 #define UPDATE(X) edln->ui_update(edln->uiptr, X, FALSE)
23 #define UPDATE_MOVED(X) edln->ui_update(edln->uiptr, X, TRUE)
26 /*{{{ Alloc */
29 static bool edln_pspc(Edln *edln, int n)
31 char *np;
32 int pa;
34 if(edln->palloced<edln->psize+1+n){
35 pa=edln->palloced+n;
36 pa|=(EDLN_ALLOCUNIT-1);
37 np=ALLOC_N(char, pa);
39 if(np==NULL){
40 warn_err();
41 return FALSE;
44 memmove(np, edln->p, edln->point*sizeof(char));
45 memmove(np+edln->point+n, edln->p+edln->point,
46 (edln->psize-edln->point+1)*sizeof(char));
47 free(edln->p);
48 edln->p=np;
49 edln->palloced=pa;
50 }else{
51 memmove(edln->p+edln->point+n, edln->p+edln->point,
52 (edln->psize-edln->point+1)*sizeof(char));
55 edln->psize+=n;
56 edln->modified=1;
57 return TRUE;
61 static bool edln_rspc(Edln *edln, int n)
63 char *np;
64 int pa;
66 if(n+edln->point>=edln->psize)
67 n=edln->psize-edln->point;
69 if(n==0)
70 return TRUE;
72 if((edln->psize+1-n)<(edln->palloced&~(EDLN_ALLOCUNIT-1))){
73 pa=edln->palloced&~(EDLN_ALLOCUNIT-1);
74 np=ALLOC_N(char, pa);
76 if(np==NULL){
77 warn_err();
78 goto norm;
81 memmove(np, edln->p, edln->point*sizeof(char));
82 memmove(np+edln->point, edln->p+edln->point+n,
83 (edln->psize-edln->point+1-n)*sizeof(char));
84 free(edln->p);
85 edln->p=np;
86 edln->palloced=pa;
87 }else{
88 norm:
89 memmove(edln->p+edln->point, edln->p+edln->point+n,
90 (edln->psize-edln->point+1-n)*sizeof(char));
92 edln->psize-=n;
94 edln->modified=1;
95 return TRUE;
99 static void edln_clearstr(Edln *edln)
101 if(edln->p!=NULL)
102 free(edln->p);
103 edln->palloced=0;
104 edln->psize=0;
108 static bool edln_initstr(Edln *edln, const char *p)
110 int l=strlen(p), al;
112 al=(l+1)|(EDLN_ALLOCUNIT-1);
114 edln->p=ALLOC_N(char, al);
116 if(edln->p==NULL){
117 warn_err();
118 return FALSE;
121 edln->palloced=al;
122 edln->psize=l;
123 strcpy(edln->p, p);
125 return TRUE;
129 static bool edln_setstr(Edln *edln, const char *p)
131 edln_clearstr(edln);
132 return edln_initstr(edln, p);
136 /*}}}*/
139 /*{{{ Insert */
142 bool edln_insch(Edln *edln, char ch)
144 if(edln_pspc(edln, 1)){
145 edln->p[edln->point]=ch;
146 edln->point++;
147 UPDATE_MOVED(edln->point-1);
148 return TRUE;
150 return FALSE;
154 bool edln_ovrch(Edln *edln, char ch)
156 edln_delete(edln);
157 return edln_insch(edln, ch);
161 bool edln_insstr(Edln *edln, const char *str)
163 int l;
165 if(str==NULL)
166 return FALSE;
168 l=strlen(str);
170 return edln_insstr_n(edln, str, l);
174 bool edln_insstr_n(Edln *edln, const char *str, int l)
176 if(!edln_pspc(edln, l))
177 return FALSE;
179 memmove(&(edln->p[edln->point]), str, l);
180 edln->point+=l;
181 UPDATE_MOVED(edln->point-l);
183 return TRUE;
187 /*}}}*/
190 /*{{{ Movement */
193 void edln_back(Edln *edln)
195 if(edln->point>0){
196 edln->point--;
197 UPDATE_MOVED(edln->point);
202 void edln_forward(Edln *edln)
204 if(edln->point<edln->psize){
205 edln->point++;
206 UPDATE_MOVED(edln->point-1);
211 void edln_bol(Edln *edln)
213 if(edln->point!=0){
214 edln->point=0;
215 UPDATE_MOVED(0);
220 void edln_eol(Edln *edln)
222 int o=edln->point;
224 if(edln->point!=edln->psize){
225 edln->point=edln->psize;
226 UPDATE_MOVED(o);
231 void edln_bskip_word(Edln *edln)
233 int p=edln->point-1;
235 while(p>0){
236 if(isalnum(edln->p[p]))
237 goto fnd;
238 p--;
240 return;
242 fnd:
243 while(p>0){
244 if(!isalnum(edln->p[p])){
245 p++;
246 break;
248 p--;
250 edln->point=p;
251 UPDATE_MOVED(edln->point);
255 void edln_skip_word(Edln *edln)
257 int p=edln->point;
258 int o=p;
260 while(p<edln->psize){
261 if(!isalnum(edln->p[p]))
262 goto fnd;
263 p++;
265 return;
267 fnd:
268 while(p<edln->psize){
269 if(isalnum(edln->p[p]))
270 break;
271 p++;
273 edln->point=p;
274 UPDATE_MOVED(o);
278 void edln_set_point(Edln *edln, int point)
280 int o=edln->point;
282 if(point<0)
283 point=0;
284 else if(point>edln->psize)
285 point=edln->psize;
287 edln->point=point;
289 if(o<point)
290 UPDATE_MOVED(o);
291 else
292 UPDATE_MOVED(point);
296 /*}}}*/
299 /*{{{ Delete */
302 void edln_delete(Edln *edln)
304 edln_rspc(edln, 1);
305 UPDATE(edln->point);
309 void edln_backspace(Edln *edln)
311 if(edln->point!=0){
312 edln_back(edln);
313 edln_delete(edln);
314 UPDATE_MOVED(edln->point);
318 void edln_kill_to_eol(Edln *edln)
320 edln_rspc(edln, edln->psize-edln->point);
321 UPDATE(edln->point);
325 void edln_kill_to_bol(Edln *edln)
327 int p=edln->point;
329 edln_bol(edln);
330 edln_rspc(edln, p);
331 edln->point=0;
332 UPDATE_MOVED(0);
336 void edln_kill_line(Edln *edln)
338 edln_bol(edln);
339 edln_kill_to_eol(edln);
340 UPDATE_MOVED(0);
344 void edln_kill_word(Edln *edln)
346 int p=edln->point;
347 int o=p;
349 if(!isalnum(edln->p[p])){
350 while(p<edln->psize){
351 p++;
352 if(isalnum(edln->p[p]))
353 break;
355 }else{
356 while(p<edln->psize){
357 p++;
358 if(!isalnum(edln->p[p]))
359 break;
362 edln_rspc(edln, p-edln->point);
363 UPDATE(o);
367 void edln_bkill_word(Edln *edln)
369 int p=edln->point, p2;
371 if(p==0)
372 return;
374 p--;
375 if(!isalnum(edln->p[p])){
376 while(p>0){
377 p--;
378 if(isalnum(edln->p[p])){
379 p++;
380 break;
383 }else{
384 while(p>0){
385 p--;
386 if(!isalnum(edln->p[p])){
387 p++;
388 break;
393 p2=edln->point;
394 edln->point=p;
395 edln_rspc(edln, p2-p);
396 UPDATE_MOVED(edln->point);
400 /*}}}*/
403 /*{{{ Selection */
406 void edln_set_mark(Edln *edln)
408 edln->mark=edln->point;
412 void edln_clear_mark(Edln *edln)
414 int m=edln->mark;
415 edln->mark=-1;
417 if(m<edln->point)
418 UPDATE(m);
419 else
420 UPDATE(edln->point);
424 static void edln_do_copy(Edln *edln, bool del)
426 int beg, end;
428 if(edln->mark<0 || edln->point==edln->mark)
429 return;
431 if(edln->point<edln->mark){
432 beg=edln->point;
433 end=edln->mark;
434 }else{
435 beg=edln->mark;
436 end=edln->point;
439 set_selection(edln->p+beg, end-beg);
441 if(del){
442 edln->point=beg;
443 edln_rspc(edln, end-beg);
445 edln->mark=-1;
447 UPDATE(beg);
451 void edln_cut(Edln *edln)
453 edln_do_copy(edln, TRUE);
457 void edln_copy(Edln *edln)
459 edln_do_copy(edln, FALSE);
463 /*}}}*/
466 /*{{{ History */
469 static int hist_head=EDLN_HISTORY_SIZE;
470 static int hist_count=0;
471 static char *hist[EDLN_HISTORY_SIZE];
474 void edlnhist_push(const char *str)
476 char *strc=scopy(str);
478 if(strc==NULL){
479 warn_err();
480 return;
483 hist_head--;
484 if(hist_head<0)
485 hist_head=EDLN_HISTORY_SIZE-1;
487 if(hist_count==EDLN_HISTORY_SIZE)
488 free(hist[hist_head]);
489 else
490 hist_count++;
492 hist[hist_head]=strc;
496 void edlnhist_clear()
498 while(hist_count!=0){
499 free(hist[hist_head]);
500 hist_count--;
501 if(++hist_head==EDLN_HISTORY_SIZE)
502 hist_head=0;
504 hist_head=EDLN_HISTORY_SIZE;
508 static void edln_do_set_hist(Edln *edln, int e)
510 edln->histent=e;
511 edln_setstr(edln, hist[e]);
512 edln->point=edln->psize;
513 edln->mark=-1;
514 edln->modified=FALSE;
515 UPDATE_MOVED(0);
519 void edln_history_prev(Edln *edln)
521 int e;
523 if(edln->histent==-1){
524 if(hist_count==0)
525 return;
526 edln->tmp_p=edln->p;
527 edln->p=NULL;
528 e=hist_head;
529 }else{
530 e=edln->histent;
531 if(e==(hist_head+hist_count-1)%EDLN_HISTORY_SIZE)
532 return;
533 e=(e+1)%EDLN_HISTORY_SIZE;
536 edln_do_set_hist(edln, e);
540 void edln_history_next(Edln *edln)
542 int e=edln->histent;
544 if(edln->histent==-1)
545 return;
547 if(edln->histent==hist_head){
548 edln->histent=-1;
549 if(edln->p!=NULL)
550 free(edln->p);
551 edln->p=edln->tmp_p;
552 edln->tmp_p=NULL;
553 edln->point=strlen(edln->p);
554 edln->mark=-1;
555 edln->modified=TRUE;
556 UPDATE_MOVED(0);
557 return;
560 /* e=edln->histent-1;*/
562 edln_do_set_hist(edln, (e+EDLN_HISTORY_SIZE-1)%EDLN_HISTORY_SIZE);
566 /*}}}*/
569 /*{{{ Init/deinit */
572 bool edln_init(Edln *edln, const char *p)
574 if(p==NULL)
575 p="";
577 if(!edln_initstr(edln, p))
578 return FALSE;
580 edln->point=edln->psize;
581 edln->mark=-1;
582 edln->histent=-1;
583 edln->modified=FALSE;
584 edln->completion_handler=NULL;
585 edln->tmp_p=NULL;
587 return TRUE;
591 void edln_deinit(Edln *edln)
593 if(edln->p!=NULL){
594 free(edln->p);
595 edln->p=NULL;
597 if(edln->tmp_p!=NULL){
598 free(edln->tmp_p);
599 edln->tmp_p=NULL;
604 char* edln_finish(Edln *edln)
606 char *p=edln->p;
608 /*if(edln->modified)*/
609 edlnhist_push(p);
611 edln->p=NULL;
612 edln->psize=edln->palloced=0;
614 stripws(p);
615 return p;
618 /*}}}*/