home *** CD-ROM | disk | FTP | other *** search
- /* housekeeping.c -- Generally editor fiddly stuff
- Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
-
- This file is part of Jade.
-
- Jade is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- Jade is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Jade; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "jade.h"
- #include "jade_protos.h"
-
- _PR void keepposaddx(TX *, long, long, long);
- _PR void keeppossubx(TX *, long, long, long);
- _PR void keepposaddy(TX *, long, long);
- _PR void keeppossuby(TX *, long, long);
- _PR void keeppossplity(TX *, long, long);
- _PR void keepposjoiny(TX *, long, long);
- _PR void resyncx(VW *);
- _PR void resyncy(VW *);
- _PR void resyncxy(VW *);
- _PR void setstartcol(VW *, long);
- _PR void setstartline(VW *, long);
- _PR void resetallviews(TX *);
-
- /*
- * The next few routines deal with updating the various references to
- * coordinates throughout the views after chunks have been deleted and
- * inserted.
- */
- void
- keepposaddx(TX *tx, long addx, long xpos, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(x,y) if((y == ypos) && (x >= xpos)) x += addx
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
- UPD(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
- UPD(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
- UPD(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
- UPD(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
- UPD(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
- #if 1
- if((tx->tx_ModStart.pos_Line == ypos) && (tx->tx_ModStart.pos_Col > xpos))
- tx->tx_ModStart.pos_Col += addx;
- #else
- UPD(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
- #endif
- UPD(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
-
- #undef UPD(x,y)
- }
-
- void
- keeppossubx(TX *tx, long subx, long xpos, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(x,y) if((y == ypos) && (x >= xpos)) { if((x -= subx) < xpos) x = xpos; }
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
- UPD(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
- UPD(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
- UPD(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
- UPD(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
- UPD(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
-
- UPD(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
- #if 1
- if((tx->tx_ModEnd.pos_Line == ypos) && (tx->tx_ModEnd.pos_Col > xpos))
- {
- if((tx->tx_ModEnd.pos_Col -= subx) < xpos)
- tx->tx_ModEnd.pos_Col = xpos;
- }
- #else
- UPD(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
- #endif
-
- #undef UPD(x,y)
- }
-
- /*
- * Whole lines only please
- */
- void
- keepposaddy(TX *tx, long addy, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(y) if(y >= ypos) y += addy
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD(thisvw->vw_CursorPos.pos_Line);
- UPD(thisvw->vw_BlockS.pos_Line);
- UPD(thisvw->vw_BlockE.pos_Line);
- if(thisvw != CurrVW)
- UPD(thisvw->vw_StartLine);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD(VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD(tx->tx_SavedCPos.pos_Line);
- UPD(tx->tx_SavedWPos.pos_Line);
- UPD(tx->tx_SavedBlockPos[0].pos_Line);
- UPD(tx->tx_SavedBlockPos[1].pos_Line);
-
- #if 1
- if(tx->tx_ModStart.pos_Line > ypos)
- tx->tx_ModStart.pos_Line += addy;
- #else
- UPD(tx->tx_ModStart.pos_Line);
- #endif
- UPD(tx->tx_ModEnd.pos_Line);
-
- #undef UPD(y)
- }
-
- /*
- * Whole lines only please
- */
- void
- keeppossuby(TX *tx, long suby, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(y) if(y > ypos) { if((y -= suby) < ypos) y = ypos; }
- #define UPD2(x,y) if(y >= ypos) { if((y -= suby) < ypos) {y = ypos; x = 0; }}
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
- UPD2(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
- UPD2(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
- if(thisvw != CurrVW)
- UPD(thisvw->vw_StartLine);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD2(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD2(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
- UPD2(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
- UPD2(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
- UPD2(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
-
- UPD2(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
- #if 1
- if(tx->tx_ModEnd.pos_Line > ypos)
- {
- if((tx->tx_ModEnd.pos_Line -= suby) < ypos)
- {
- tx->tx_ModEnd.pos_Line = ypos;
- tx->tx_ModEnd.pos_Col = 0;
- }
- }
- #else
- UPD2(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
- #endif
-
- #undef UPD(y)
- #undef UPD2(x,y)
- }
-
- /*
- * Use when splitting a line into 2, cursor should be at position of split
- */
- void
- keeppossplity(TX *tx, long xpos, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(y) if(y > ypos) y++
- #define UPD2(x,y) if((y == ypos) && (x >= xpos)) { x -= xpos; y++; } else if(y > ypos) y++
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
- UPD2(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
- UPD2(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
- if(thisvw != CurrVW)
- UPD(thisvw->vw_StartLine);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD2(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD2(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
- UPD2(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
- UPD2(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
- UPD2(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
-
- #if 1
- if((tx->tx_ModStart.pos_Line == ypos) && (tx->tx_ModStart.pos_Col > xpos))
- {
- tx->tx_ModStart.pos_Col -= xpos;
- tx->tx_ModStart.pos_Line++;
- }
- else if(tx->tx_ModStart.pos_Line > ypos)
- tx->tx_ModStart.pos_Line++;
- #else
- UPD2(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
- #endif
- UPD2(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
-
- #undef UPD(y)
- #undef UPD2(x,y)
- }
-
- /*
- * Use when compacting 2 adjacent lines into one
- */
- void
- keepposjoiny(TX *tx, long xpos, long ypos)
- {
- VW *thisvw;
- Mark *thismark;
-
- #define UPD(y) if(y > ypos) y--
- #define UPD2(x,y) if(y > ypos) { if(y == ypos + 1) x += xpos; y--; }
-
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- UPD2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
- UPD2(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
- UPD2(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
- if(thisvw != CurrVW)
- UPD(thisvw->vw_StartLine);
- }
- }
- for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
- {
- UPD2(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
- }
- UPD2(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
- UPD2(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
- UPD2(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
- UPD2(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
- UPD2(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
- UPD2(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
-
- #undef UPD(y)
- #undef UPD2(x,y)
- }
-
- /*
- * These routines are called to recalculate the cursor's position on the
- * screen,
- */
- void
- resyncx(VW *vw)
- {
- while((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) >= vw->vw_MaxX)
- {
- vw->vw_StartCol += vw->vw_XStep;
- vw->vw_Flags |= VWFF_FORCE_REFRESH;
- }
- while(vw->vw_CursorPos.pos_Col < vw->vw_StartCol)
- {
- vw->vw_StartCol -= vw->vw_XStep;
- if(vw->vw_StartCol < 0)
- vw->vw_StartCol = 0;
- vw->vw_Flags |= VWFF_FORCE_REFRESH;
- }
- }
-
- void
- resyncy(VW *vw)
- {
- TX *tx = vw->vw_Tx;
- long y = vw->vw_CursorPos.pos_Line - vw->vw_LastDisplayOrigin.pos_Line;
- if(y < 0)
- {
- if(-y > vw->vw_YStep)
- vw->vw_StartLine = vw->vw_CursorPos.pos_Line;
- else
- {
- vw->vw_StartLine -= vw->vw_YStep;
- if(vw->vw_StartLine < 0)
- vw->vw_StartLine = 0;
- }
- }
- else if(y >= vw->vw_MaxY)
- {
- if((vw->vw_MaxY + vw->vw_YStep) <= y)
- vw->vw_StartLine = vw->vw_CursorPos.pos_Line - vw->vw_MaxY + 1;
- else
- {
- vw->vw_StartLine += vw->vw_YStep;
- if(vw->vw_StartLine >= tx->tx_NumLines)
- vw->vw_StartLine = tx->tx_NumLines - 1;
- }
- }
- }
-
- void
- resyncxy(VW *vw)
- {
- vw->vw_LastDisplayOrigin = vw->vw_DisplayOrigin;
- resyncx(vw);
- resyncy(vw);
- }
-
- void
- setstartcol(VW *vw, long col)
- {
- if(vw->vw_StartCol != col)
- {
- vw->vw_Flags |= VWFF_FORCE_REFRESH;
- vw->vw_StartCol = col;
- }
- }
-
- void
- setstartline(VW *vw, long line)
- {
- long cline = vw->vw_StartLine;
- if(line != cline)
- {
- long yord = vw->vw_CursorPos.pos_Line - cline;
- vw->vw_StartLine = line;
- if(!(vw->vw_Flags & VWFF_FORCE_REFRESH))
- {
- long diff = line - cline;
- if((diff > 0) && (diff <= vw->vw_MaxScroll))
- {
- long ypos = vw->vw_MaxY - 1;
- scrollvw(vw, diff);
- redrawlines(vw, cline + ypos, line + ypos + 1);
- }
- else if((diff < 0) && (diff >= -vw->vw_MaxScroll))
- {
- scrollvw(vw, diff);
- redrawlines(vw, line, cline);
- }
- else
- vw->vw_Flags |= VWFF_FORCE_REFRESH;
- }
- else
- vw->vw_Flags |= VWFF_FORCE_REFRESH;
- vw->vw_CursorPos.pos_Line = line + yord;
- if(vw->vw_CursorPos.pos_Line >= vw->vw_Tx->tx_NumLines)
- vw->vw_CursorPos.pos_Line = vw->vw_Tx->tx_NumLines - 1;
- }
- }
-
- /*
- * This makes all views of this file have their cursor at the top of the
- * file, it also refreshes each view.
- */
- void
- resetallviews(TX *tx)
- {
- VW *thisvw;
- for(thisvw = ViewChain; thisvw; thisvw = thisvw->vw_Next)
- {
- if(thisvw->vw_Tx == tx)
- {
- thisvw->vw_CursorPos.pos_Col = 0;
- thisvw->vw_CursorPos.pos_Line = 0;
- thisvw->vw_StartCol = 0;
- thisvw->vw_StartLine = 0;
- thisvw->vw_BlockStatus = -1;
- thisvw->vw_Flags |= VWFF_FORCE_REFRESH;
- thisvw->vw_NonStdTitle = FALSE;
- stdtitle(thisvw);
- }
- tx->tx_SavedCPos.pos_Col = 0;
- tx->tx_SavedCPos.pos_Line = 0;
- tx->tx_SavedWPos.pos_Col = 0;
- tx->tx_SavedWPos.pos_Line = 0;
- tx->tx_SavedBlockStatus = -1;
- }
- }
-