/* vi:ts=4:sw=4
*
* VIM - Vi IMproved
*
* Code Contributions By: Bram Moolenaar mool@oce.nl
* Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
/*
* help.c: display help from the vim.hlp file
*/
#include "vim.h"
#include "globals.h"
#include "proto.h"
#include "param.h"
#ifdef JP
#include "jp.h"
#endif
static long helpfilepos; /* position in help file */
static FILE *helpfd; /* file descriptor of help file */
#define MAXSCREENS 52 /* one screen for a-z and A-Z */
void
help()
{
int c;
int eof;
int screens;
int i;
long filepos[MAXSCREENS]; /* seek position for each screen */
int screennr; /* screen number; index == 0, 'c' == 1, 'd' == 2, etc */
#ifdef MSDOS
char *fnamep;
#endif
/*
* try to open the file specified by the "helpfile" option
*/
if ((helpfd = fopen(p_hf, READBIN)) == NULL)
{
#ifdef MSDOS
/*
* for MSDOS: try the DOS search path
*/
fnamep = searchpath("vim.hlp");
if (fnamep == NULL || (helpfd = fopen(fnamep, READBIN)) == NULL)
{
smsg("Sorry, help file \"%s\" and \"vim.hlp\" not found", p_hf);
return;
}
#else
smsg("Sorry, help file \"%s\" not found", p_hf);
return;
#endif
}
helpfilepos = 0;
screennr = 0;
for (i = 0; i < MAXSCREENS; ++i)
filepos[i] = 0;
State = HELP;
for (;;)
{
screens = redrawhelp(); /* show one or more screens */
eof = (screens < 0);
if (!eof && screennr + screens < MAXSCREENS)
filepos[screennr + screens] = ftell(helpfd);
if ((c = vgetc()) == '\n' || c == '\r' || c == Ctrl('C') || c == ESC)
break;
if (c == ' ' ||
#if defined(MSDOS) && !defined(DOSGEN)
(c == K_NUL && vpeekc() == 'Q') || /* page down */
#endif
c == Ctrl('F')) /* one screen forwards */
{
if (screennr < MAXSCREENS && !eof)
++screennr;
}
else if (c == 'a') /* go to first screen */
screennr = 0;
else if (c == 'b' ||
#if defined(MSDOS) && !defined(DOSGEN)
(c == K_NUL && vpeekc() == 'I') || /* page up */
#endif
c == Ctrl('B')) /* go one screen backwards */
{
if (screennr > 0)
--screennr;
}
else if (isalpha(c)) /* go to specified screen */
{
if (isupper(c))
c = c - 'A' + 'z' + 1; /* 'A' comes after 'z' */
screennr = c - 'b';
}
#if defined(MSDOS) && !defined(DOSGEN)
if (c == K_NUL)
c = vgetc();
#endif
for (i = screennr; i > 0; --i)
if (filepos[i])
break;
fseek(helpfd, filepos[i], 0);
while (i < screennr)
{
while ((c = getc(helpfd)) != '\f' && c != -1)
;
if (c == -1)
break;
filepos[++i] = ftell(helpfd); /* store the position just after the '\f' */
}
screennr = i; /* required when end of file reached */
helpfilepos = filepos[screennr];
}
State = NORMAL;
script_winsize_pp();
fclose(helpfd);
updateScreen(CLEAR);
}
int
redrawhelp()
{
int nextc = -1;
int col;
int line = 0;
int screens = 1;
char *cp;
#ifdef JP
int kanji = FALSE;
static char *kin, *kout, kcode = NUL;
#ifdef ONEW
char *Onew_version();
#endif
if (kcode != JP_DISP)
{
kin = kanjiin(JP_DISP);
kout= kanjiout(JP_DISP);
kcode = JP_DISP;
}
#endif
fseek(helpfd, helpfilepos, 0);
outstr(T_ED);
windgoto(0,0);
while(!feof(helpfd))
{
#ifdef JP
char tmp[IOSIZE];
int len;
#endif
cp = IObuff;
while( (nextc = getc(helpfd)) != -1 )
{
*cp++ = nextc;
if (nextc == '\n' || nextc == '\f')
break;
}
*cp = NUL;
#ifdef JP
len = kanjiconvsfrom(IObuff, cp - IObuff, tmp, IOSIZE, NULL,
#ifdef MSDOS
JP_SANY,
#else
JP_ANY,
#endif
NULL);
tmp[len] = NUL;
for(cp = tmp; *cp; cp++)
#else /* JP */
for(cp = IObuff; *cp; cp++)
#endif /* JP */
{
if ((nextc = *cp) == Ctrl('B')) /* begin of invert */
outstr(T_TI);
else if (nextc == Ctrl('E')) /* end of invert */
outstr(T_TP);
else if (nextc == '\f') /* start of next screen */
{
if (line < Rows - 24)
{
++screens;
/* outchar('\n');
++line;
*/
windgoto(++line, 0);
col = 0;
}
else
goto nextscreen;
}
#ifdef DOSGEN
else if (nextc == '\t')
{
do
outchar(' ');
while(++col % 8);
}
#endif
#ifdef JP
else if (IsKanji(nextc))
{
if (!kanji)
{
if (kin) outstr(kin);
kanji = TRUE;
}
kanjito(cp, cp + 1, JP_DISP);
outchar(*cp);
outchar(* ++cp);
col += 2;
}
#endif
else
{
#ifdef JP
if (kanji)
{
if (kout) outstr(kout);
kanji = FALSE;
}
#endif
if (nextc == '\n')
{
windgoto(++line, 0);
col = 0;
}
else
{
outchar((char) nextc);
col++;
}
}
}
}
nextscreen:
#ifdef JP
if (kanji && kout) outstr(kout);
# ifdef ONEW
sscanf(Onew_version(), "%s", IObuff + 80);
sprintf(IObuff, "%s+%s", JpVersion, IObuff + 80);
# else
sprintf(IObuff, "%s/%s", JpVersion, Version);
# endif
windgoto(0, (int)(Columns - strlen(IObuff) - 1));
outstrn(IObuff);
#else
windgoto(0, (int)(Columns - strlen(Version) - 1));
outstrn(Version);
#endif
col = (int)Columns - 52;
if (col < 0)
col = 0;
windgoto((int)Rows - 1, col);
outstrn("<space = next; return = quit; a = index; b = back>");
return (nextc == -1 ? -1 : screens);
}
syntax highlighted by Code2HTML, v. 0.9.1