home *** CD-ROM | disk | FTP | other *** search
- /* 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"
-
- 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 == ' ' ||
- #ifdef MSDOS
- (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' ||
- #ifdef MSDOS
- (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';
- }
- #ifdef MSDOS
- 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;
- int col;
- int line = 0;
- int screens = 1;
-
- fseek(helpfd, helpfilepos, 0);
- outstr(T_ED);
- windgoto(0,0);
- while ((nextc = getc(helpfd)) != -1 && (nextc != '\f' || line < Rows - 24))
- {
- if (nextc == 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 */
- {
- ++screens;
- outchar('\n');
- ++line;
- }
- else
- {
- outchar((char)nextc);
- if (nextc == '\n')
- ++line;
- }
- }
- windgoto(0, (int)(Columns - strlen(Version) - 1));
- outstrn(Version);
- 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);
- }
-