/*** Join two lines and strip spaces on the next ***/ void join_strip( Project p ) { LINE *ln; if((ln = p->edited->next) != NULL) { STRPTR data; ULONG i; inv_curs(p, FALSE); p->nbc = p->edited->size; for(i=0, data=ln->stream; TypeChar[*data] == SPACE && i<ln->size; i++, data++); reg_group_by(&p->undo); if(i != ln->size) { /* Do not add a blank if there is already one */ if( p->nbc > 0 && TypeChar[ p->edited->stream[ p->nbc-1 ] ] != SPACE ) add_char(&p->undo, p->edited, p->nbc, ' '); if( insert_str(&p->undo, p->edited, p->edited->size, data, ln->size-i) == 0 ) ThrowError(Wnd, ErrMsg(ERR_NOMEM)); } /* ln can't be the first */ del_line(&p->undo, NULL, ln); p->max_lines--; reg_group_by(&p->undo); prop_adj(p); /* Refresh screen */ p->nbrc = p->nbrwc = x2pos(p->edited, p->nbc); REDRAW_CURLINE( p ); draw_info( p ); scroll_up(p, p->edited->next, p->ycurs, center_horiz(p)); inv_curs(p,TRUE); } }
/*** Remove the char before the cursor ***/ void back_space(Project p, BYTE word) { if(p->nbc!=0) { ULONG nbc = word ? backward_word(p->edited,p->nbc-1) : p->nbc-1; rem_chars(&p->undo, p->edited, nbc, p->nbc-1); /* Set cursor position and redraws it */ inv_curs(p,FALSE); REDRAW_CURLINE(p); p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc=nbc); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; if( (nbc = center_horiz(p)) != p->left_pos ) scroll_xy(p, nbc, p->top_line, FALSE); inv_curs(p,TRUE); draw_info( p ); } else if(p->edited->prev != NULL) { p->edited = p->edited->prev; p->nbc = p->edited->size; /* Join previous and current line */ if( join_lines(&p->undo, p->edited, p->edited->next) ) { /* Move cursor to the end of previous line */ p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->max_lines--; p->nbl--; /* Require to scroll the display? */ inv_curs(p, FALSE); if(p->ycurs>gui.topcurs) scroll_up(p, p->edited->next, p->ycurs-=YSIZE, center_horiz(p)); else p->top_line--, p->show = p->edited, p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; SetAPen(RP, pen.fg); REDRAW_CURLINE(p); /* Redraw the cursor: */ inv_curs(p,TRUE); draw_info(p); prop_adj(p); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); } }
/*** Move cursor to the left ***/ void curs_left(Project p, BYTE word) { register LINE *prev; if(p->nbc != 0) { inv_curs(p,FALSE); if(word) p->nbc = backward_word(p->edited, p->nbc-1); else p->nbc--; p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->xcurs = (p->nbrc-p->left_pos) * XSIZE + gui.left; /* Is it gone outside edit area? */ if(p->nbrc<p->left_pos) scroll_xy(p, adjust_leftpos(p, -gui.xstep), p->top_line, FALSE); if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p,TRUE); draw_info( p ); } else if( ( prev = p->edited->prev ) ) { /* jump up */ p->nbrwc = x2pos(prev, prev->size); curs_up(p); } }
/*** Split line ***/ void split_curline( Project p ) { if( split_line(&p->undo, p->edited, p->nbc, &p->nbrwc, prefs.auto_indent) ) { register LINE *ln = p->edited; /* Redraw line where cursor is */ Move(RP,gui.left,p->ycurs); write_text(p, ln); /* A line has been added */ p->max_lines++; p->nbrwc = x2pos(ln,p->nbrwc); /* Scroll manually the display and redraw new line */ if(p->ycurs < gui.botcurs) { ScrollRaster(RP, 0, -YSIZE, gui.left,p->ycurs+YSIZE-BASEL,gui.right,gui.bottom); Move(RP,gui.left,p->ycurs+YSIZE); ln = ln->next; write_text(p, ln); prop_adj(p); } /* Go down one line */ curs_down(p); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); }
/*** Move cursor incrementally (paste) ***/ void move_cursor(Project p, LONG dx, LONG dy) { LINE *ln; LONG nb=dy; inv_curs(p, FALSE); if(nb < 0) for(ln=p->edited; nb++; ln=ln->prev); else for(ln=p->edited; nb--; ln=ln->next); p->edited = ln; p->nbl += dy; p->nbrwc = p->nbrc = x2pos(ln,p->nbc = dx); dx = center_horiz(p); /* Don't scroll if top_line changed! (whole redraw instead) */ if(dx != p->left_pos && dy == 0) scroll_xy(p, dx, p->top_line, TRUE); else { nb = center_vert(p) - p->top_line; for(p->top_line += nb,ln=p->show; nb--; ln=ln->next); p->show = ln; p->left_pos = dx; } p->ycurs = (p->nbl-p->top_line)*YSIZE + gui.topcurs; p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; draw_info( p ); }
/*** One pos right ***/ void curs_right(Project p, BYTE word) { if(p->nbc < p->edited->size) { inv_curs(p,FALSE); if(word) p->nbc = forward_word(p->edited, p->nbc); else p->nbc++; p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->xcurs = (p->nbrc-p->left_pos) * XSIZE + gui.left; /* Move the cursor */ /* Is it gone outside edit area? */ if(p->nbrc>=p->left_pos+gui.nbcol) scroll_xy(p, adjust_leftpos(p, gui.xstep), p->top_line, FALSE); if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p,TRUE); draw_info( p ); } else if(p->edited->next) { /* jump down to next line */ p->nbrwc = 0; curs_down(p); } }
/*** Mark: stream selection ***/ BYTE move_stream_selection(Project p, LONG xn, LONG yn) { LONG yline; /* Nb. of line marked */ LINE *ln; /* Running pointer */ BYTE ret; /* Autoscroll ? */ WORD y; /* VPos of item sel */ /* Vertical autoscroll ? */ ret = (yn<p->top_line ? 2 : (yn>=(LONG)(p->top_line+gui.nbline) ? 1 : 0)); if(yn<0) yn=0; if(yn>=p->max_lines) yn=p->max_lines-1,ret=0; yline=p->ccp.yc; ln=p->ccp.cline; /* top_line may changed */ y=(yline-p->top_line)*YSIZE+gui.topcurs; /* If new selection point is situated after the prece- ** ** eding one (ie:looking afterward in linked list) */ if( yn>yline || (yn==yline && xn>p->ccp.xp) ) for(; yline<yn; yline++, ln=ln->next, y+=YSIZE) { if(ln->flags && yline<=p->ccp.yp) if(yline == p->ccp.yp ) p->ccp.startsel = (p->ccp.select != WORD_TYPE ? p->ccp.xp : x2pos(ln, backward_word(ln, find_nbc(ln,p->ccp.xp)))), ln->flags = (p->ccp.select == LINE_TYPE ? WHOLESEL : FIRSTSEL); else ln->flags=0; else ln->flags=WHOLESEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); } else /* New selection point is before the previous */ for(; yline>yn; yline--, ln=ln->prev, y-=YSIZE) { if(ln->flags && yline>=p->ccp.yp) if(yline == p->ccp.yp) p->ccp.endsel = (p->ccp.select != WORD_TYPE ? p->ccp.xp : x2pos(ln, forward_word(ln, find_nbc(ln,p->ccp.xp)))), ln->flags = (p->ccp.select == LINE_TYPE ? WHOLESEL : LASTSEL); else ln->flags=0; else ln->flags=WHOLESEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); } /* Current point will be the previous */ p->ccp.cline=ln; p->ccp.yc=yn; p->ccp.xc=xn; /* Update last-selected line */ { register UBYTE Set = 0; if(p->ccp.select != LINE_TYPE) if(yn == p->ccp.yp) { ln->flags = FIRSTSEL | LASTSEL; if(xn < p->ccp.xp) p->ccp.startsel=xn, p->ccp.endsel=p->ccp.xp; else p->ccp.startsel=p->ccp.xp, p->ccp.endsel=xn; Set = 3; } else if( yn > p->ccp.yp ) ln->flags=LASTSEL, p->ccp.endsel=xn, Set = 2; else ln->flags=FIRSTSEL,p->ccp.startsel=xn, Set = 1; else ln->flags = WHOLESEL; /* Adjust selection for word selection */ if(p->ccp.select == WORD_TYPE) { if(Set & 1) p->ccp.startsel = x2pos(ln, backward_word(ln, find_nbc(ln,p->ccp.startsel))); if(Set & 2) p->ccp.endsel = x2pos(ln, forward_word (ln, find_nbc(ln,p->ccp.endsel))); } } /* Last line can overlap edit area */ if(gui.topcurs<=y && y<=gui.botcurs) Move(RP, gui.left, y),write_text(p,ln); return ret; }