#include <sys/queue.h>
#include <ctype.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "def.h"
#define percint(n1, n2) ((n1 * (int) n2) * 0.1)
int
gotobol(int f, int n)
{
if (n == 0)
return (TRUE);
curwp->w_doto = 0;
return (TRUE);
}
int
backchar(int f, int n)
{
struct line *lp;
if (n < 0)
return (forwchar(f, -n));
while (n--) {
if (curwp->w_doto == 0) {
if ((lp = lback(curwp->w_dotp)) == curbp->b_headp) {
if (!(f & FFRAND))
(void)dobeep_msg("Beginning "
"of buffer");
return (FALSE);
}
curwp->w_dotp = lp;
curwp->w_doto = llength(lp);
curwp->w_rflag |= WFMOVE;
curwp->w_dotline--;
} else
curwp->w_doto--;
}
return (TRUE);
}
int
gotoeol(int f, int n)
{
if (n == 0)
return (TRUE);
curwp->w_doto = llength(curwp->w_dotp);
return (TRUE);
}
int
forwchar(int f, int n)
{
if (n < 0)
return (backchar(f, -n));
while (n--) {
if (curwp->w_doto == llength(curwp->w_dotp)) {
curwp->w_dotp = lforw(curwp->w_dotp);
if (curwp->w_dotp == curbp->b_headp) {
curwp->w_dotp = lback(curwp->w_dotp);
if (!(f & FFRAND))
(void)dobeep_msg("End of buffer");
return (FALSE);
}
curwp->w_doto = 0;
curwp->w_dotline++;
curwp->w_rflag |= WFMOVE;
} else
curwp->w_doto++;
}
return (TRUE);
}
int
gotobob(int f, int n)
{
if (!curwp->w_markp)
(void) setmark(f, n);
curwp->w_dotp = bfirstlp(curbp);
curwp->w_doto = 0;
curwp->w_rflag |= WFFULL;
curwp->w_dotline = 1;
if (f & FFOTHARG && n > 0) {
if (n > 9)
gotoeob(0, 0);
else
forwline(f, percint(curwp->w_bufp->b_lines, n) - 1);
}
return (TRUE);
}
int
gotoeob(int f, int n)
{
int ln;
struct line *lp;
if (!curwp->w_markp)
(void) setmark(f, n);
curwp->w_dotp = blastlp(curbp);
curwp->w_doto = llength(curwp->w_dotp);
curwp->w_dotline = curwp->w_bufp->b_lines;
lp = curwp->w_dotp;
ln = curwp->w_ntrows - 3;
if (ln < curwp->w_bufp->b_lines && ln >= 3) {
while (ln--)
curwp->w_dotp = lback(curwp->w_dotp);
curwp->w_linep = curwp->w_dotp;
curwp->w_dotp = lp;
}
if (f & FFOTHARG && n > 0) {
if (n > 9)
gotobob(0, 0);
else
backline(f, percint(curwp->w_bufp->b_lines, n));
}
curwp->w_rflag |= WFFULL;
return (TRUE);
}
int
forwline(int f, int n)
{
struct line *dlp;
if (n < 0)
return (backline(f | FFRAND, -n));
if ((dlp = curwp->w_dotp) == curbp->b_headp) {
if (!(f & FFRAND))
(void)dobeep_msg("End of buffer");
return(TRUE);
}
if ((lastflag & CFCPCN) == 0)
setgoal();
thisflag |= CFCPCN;
if (n == 0)
return (TRUE);
while (n--) {
dlp = lforw(dlp);
if (dlp == curbp->b_headp) {
curwp->w_dotp = lback(dlp);
curwp->w_doto = llength(curwp->w_dotp);
curwp->w_rflag |= WFMOVE;
if (!(f & FFRAND))
(void)dobeep_msg("End of buffer");
return (TRUE);
}
curwp->w_dotline++;
}
curwp->w_rflag |= WFMOVE;
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
return (TRUE);
}
int
backline(int f, int n)
{
struct line *dlp;
if (n < 0)
return (forwline(f | FFRAND, -n));
if ((lastflag & CFCPCN) == 0)
setgoal();
thisflag |= CFCPCN;
dlp = curwp->w_dotp;
if (lback(dlp) == curbp->b_headp) {
if (!(f & FFRAND))
(void)dobeep_msg("Beginning of buffer");
return(TRUE);
}
while (n-- && lback(dlp) != curbp->b_headp) {
dlp = lback(dlp);
curwp->w_dotline--;
}
if (n > 0 && !(f & FFRAND))
(void)dobeep_msg("Beginning of buffer");
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_rflag |= WFMOVE;
return (TRUE);
}
void
setgoal(void)
{
curgoal = getcolpos(curwp);
}
int
getgoal(struct line *dlp)
{
int c, i, col = 0;
char tmp[5];
for (i = 0; i < llength(dlp); i++) {
c = lgetc(dlp, i);
if (c == '\t') {
col = ntabstop(col, curbp->b_tabw);
} else if (ISCTRL(c) != FALSE) {
col += 2;
} else if (isprint(c))
col++;
else {
col += snprintf(tmp, sizeof(tmp), "\\%o", c);
}
if (col > curgoal)
break;
}
return (i);
}
int
forwpage(int f, int n)
{
struct line *lp;
if (!(f & FFARG)) {
n = curwp->w_ntrows - 2;
if (n <= 0)
n = 1;
} else if (n < 0)
return (backpage(f | FFRAND, -n));
lp = curwp->w_linep;
while (n--)
if ((lp = lforw(lp)) == curbp->b_headp) {
(void)dobeep_msg("End of buffer");
return(TRUE);
}
curwp->w_linep = lp;
curwp->w_rflag |= WFFULL;
for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
if (lp == curwp->w_dotp)
return (TRUE);
while (curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_dotline++;
}
curwp->w_doto = 0;
return (TRUE);
}
int
backpage(int f, int n)
{
struct line *lp, *lp2;
if (!(f & FFARG)) {
n = curwp->w_ntrows - 2;
if (n <= 0)
return (backline(f, 1));
} else if (n < 0)
return (forwpage(f | FFRAND, -n));
lp = lp2 = curwp->w_linep;
while (n-- && lback(lp) != curbp->b_headp) {
lp = lback(lp);
}
if (lp == curwp->w_linep)
(void)dobeep_msg("Beginning of buffer");
curwp->w_linep = lp;
curwp->w_rflag |= WFFULL;
for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
if (lp == curwp->w_dotp)
return (TRUE);
lp2 = lforw(lp2);
while (curwp->w_dotp != lp2) {
if (curwp->w_dotline <= curwp->w_ntrows)
goto out;
curwp->w_dotp = lback(curwp->w_dotp);
curwp->w_dotline--;
}
out:
curwp->w_doto = 0;
return (TRUE);
}
int
forw1page(int f, int n)
{
if (!(f & FFARG)) {
n = 1;
f = FFUNIV;
}
forwpage(f | FFRAND, n);
return (TRUE);
}
int
back1page(int f, int n)
{
if (!(f & FFARG)) {
n = 1;
f = FFUNIV;
}
backpage(f | FFRAND, n);
return (TRUE);
}
int
pagenext(int f, int n)
{
struct mgwin *wp;
if (wheadp->w_wndp == NULL)
return(dobeep_msg("No other window"));
wp = curwp;
(void) nextwind(f, n);
(void) forwpage(f, n);
curwp = wp;
curbp = wp->w_bufp;
return (TRUE);
}
void
isetmark(void)
{
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
curwp->w_markline = curwp->w_dotline;
}
int
setmark(int f, int n)
{
isetmark();
ewprintf("Mark set");
return (TRUE);
}
int
clearmark(int f, int n)
{
if (!curwp->w_markp)
return (FALSE);
curwp->w_markp = NULL;
curwp->w_marko = 0;
curwp->w_markline = 0;
return (TRUE);
}
int
swapmark(int f, int n)
{
struct line *odotp;
int odoto, odotline;
if (curwp->w_markp == NULL)
return(dobeep_msg("No mark in this window"));
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
odotline = curwp->w_dotline;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_dotline = curwp->w_markline;
curwp->w_markp = odotp;
curwp->w_marko = odoto;
curwp->w_markline = odotline;
curwp->w_rflag |= WFMOVE;
return (TRUE);
}
int
gotoline(int f, int n)
{
char buf[32], *bufp;
const char *err;
if (!(f & FFARG)) {
if ((bufp = eread("Goto line: ", buf, sizeof(buf),
EFNUL | EFNEW | EFCR)) == NULL)
return (ABORT);
if (bufp[0] == '\0')
return (ABORT);
n = (int)strtonum(buf, INT_MIN, INT_MAX, &err);
if (err)
return(dobeep_msgs("Line number", err));
}
return(setlineno(n));
}
int
setlineno(int n)
{
struct line *clp;
if (n >= 0) {
if (n == 0)
n++;
curwp->w_dotline = n;
clp = lforw(curbp->b_headp);
while (--n > 0) {
if (lforw(clp) == curbp->b_headp) {
curwp->w_dotline = curwp->w_bufp->b_lines;
break;
}
clp = lforw(clp);
}
} else {
curwp->w_dotline = curwp->w_bufp->b_lines + n;
clp = lback(curbp->b_headp);
while (n < 0) {
if (lback(clp) == curbp->b_headp) {
curwp->w_dotline = 1;
break;
}
clp = lback(clp);
n++;
}
}
curwp->w_dotp = clp;
curwp->w_doto = 0;
curwp->w_rflag |= WFMOVE;
return (TRUE);
}