home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
x
/
xvisrc.zoo
/
cursor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
4KB
|
147 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)cursor.c 2.2 (Chris & John Downey) 9/1/92";
#endif
/***
* program name:
xvi
* function:
PD version of UNIX "vi" editor, with extensions.
* module name:
cursor.c
* module function:
Deal with movement of the screen cursor - i.e. when the
logical cursor moves within a buffer, work out the new
position of the screen cursor within its window.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
***/
#include "xvi.h"
static void calc_position_in_line P((Xviwin *));
/*
* Update the window's variables which say where the cursor is.
* These are row, col and virtcol, curswant if w_set_want_col.
*
* We also update w_c_line_size, which is used in screen.c to
* figure out whether the cursor line has changed size or not.
*/
void
cursupdate(win)
Xviwin *win;
{
#if 0
if (win->w_curs_new == FALSE) {
return;
}
#endif
win->w_curs_new = FALSE;
/*
* Calculate physical lines from logical lines.
*/
win->w_row = cntplines(win, win->w_topline, win->w_cursor->p_line);
win->w_c_line_size = plines(win, win->w_cursor->p_line);
/*
* Calculate new position within the line.
*/
calc_position_in_line(win);
}
/*
* The cursor has moved along by nchars within the current line.
* Updating it here saves the overhead of cursupdate().
*/
void
curs_horiz(win, nchars)
Xviwin *win;
int nchars;
{
/*
* For the moment, just completely recalculate the position
* in the line. More optimisation can come later.
*/
/*
* This doesn't work for longlines, because it recalculates
* the row from a starting position of the current row, and
* so adds (c_line_size - 1) to the row:
calc_position_in_line(win);
* so we just call cursupdate() instead.
*/
win->w_curs_new = TRUE;
}
static void
calc_position_in_line(win)
Xviwin *win;
{
register Posn *curp;
register int c;
register int i;
register unsigned width;
register int ccol;
curp = win->w_cursor;
/*
* Work out the virtual column within the current line.
*/
ccol = Pb(P_number) ? NUM_SIZE : 0;
for (i = width = 0; i <= curp->p_index; i++) {
c = curp->p_line->l_text[i];
ccol += width;
width = vischar(c, (char **) NULL, ccol);
}
if (State != INSERT && c == '\t' && ! Pb(P_list) && Pb(P_tabs)) {
/*
* If we are inserting, or we're on a control
* character other than a tab, or we aren't showing
* tabs normally, the cursor goes to the first column
* of the control character representation: otherwise,
* if it's a tab & we aren't in insert mode, we place
* the cursor on the last column of the tab
* representation. (This is like the "real" vi.)
*/
ccol += width - 1;
}
/*
* If showing line numbers, adjust the virtual column within the line.
*/
win->w_virtcol = ccol - (Pb(P_number) ? NUM_SIZE : 0);
/*
* Convert virtual column to screen column by line folding.
*/
while (ccol >= win->w_ncols) {
win->w_row++;
ccol -= win->w_ncols;
}
win->w_col = ccol;
/*
* Don't go past bottom line of window. (This should only
* happen on a longline which is too big to fit in the
* window.)
*/
if (win->w_row >= win->w_nrows - 1) {
win->w_row = win->w_nrows - 2;
}
if (win->w_set_want_col) {
win->w_curswant = win->w_virtcol;
win->w_set_want_col = FALSE;
}
}