home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-22 | 52.6 KB | 2,317 lines |
- Newsgroups: comp.sources.misc
- From: mool@oce.nl (Bram Moolenaar)
- Subject: v37i008: vim - Vi IMitation editor v1.27, Part08/24
- Message-ID: <1993Apr23.173136.16790@sparky.imd.sterling.com>
- X-Md4-Signature: 828bada50568f29a1bbd1595b9b8f97b
- Date: Fri, 23 Apr 1993 17:31:36 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: mool@oce.nl (Bram Moolenaar)
- Posting-number: Volume 37, Issue 8
- Archive-name: vim/part08
- Environment: UNIX, AMIGA, MS-DOS
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 8 (of 23)."
- # Contents: vim/src/edit.c vim/src/param.c vim/src/unix.c
- # Wrapped by mool@oce-rd2 on Mon Apr 19 15:50:09 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'vim/src/edit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vim/src/edit.c'\"
- else
- echo shar: Extracting \"'vim/src/edit.c'\" \(16324 characters\)
- sed "s/^X//" >'vim/src/edit.c' <<'END_OF_FILE'
- X/* vi:ts=4:sw=4
- X *
- X * VIM - Vi IMitation
- X *
- X * Code Contributions By: Bram Moolenaar mool@oce.nl
- X * Tim Thompson twitch!tjt
- X * Tony Andrews onecom!wldrdg!tony
- X * G. R. (Fred) Walter watmath!watcgl!grwalter
- X */
- X
- X/*
- X * edit.c: functions for insert mode
- X */
- X
- X#include "vim.h"
- X#include "globals.h"
- X#include "proto.h"
- X#include "param.h"
- X#include "ops.h" /* for operator */
- X
- Xextern u_char *get_inserted();
- Xstatic void start_arrow __ARGS((void));
- Xstatic void stop_arrow __ARGS((void));
- Xstatic void stop_insert __ARGS((void));
- X
- Xint arrow_used; /* Normally FALSE, set to TRUE after hitting
- X * cursor key in insert mode. Used by vgetorpeek()
- X * to decide when to call u_sync() */
- Xint restart_edit; /* call edit when next command finished */
- Xstatic u_char *last_insert = NULL;
- X /* the text of the previous insert */
- Xstatic int last_insert_skip;
- X /* number of chars in front of the previous insert */
- Xstatic int new_insert_skip;
- X /* number of chars in front of the current insert */
- X
- X void
- Xedit(count)
- X long count;
- X{
- X u_char c;
- X u_char cc;
- X u_char *ptr;
- X linenr_t lnum;
- X int temp = 0, mode;
- X int nextc = 0;
- X
- X#ifdef DIGRAPHS
- X int inserted = 0; /* last 'normal' inserted char */
- X int backspaced = 0; /* last backspace char */
- X#endif /* DIGRAPHS */
- X
- X if (restart_edit)
- X {
- X arrow_used = TRUE;
- X restart_edit = FALSE;
- X }
- X else
- X arrow_used = FALSE;
- X
- X/*
- X * Get the current length of the redo buffer, those characters have to be
- X * skipped if we want to get to the inserted characters.
- X */
- X
- X ptr = get_inserted();
- X new_insert_skip = strlen((char *)ptr);
- X free(ptr);
- X
- X for (;;)
- X {
- X if (arrow_used) /* don't repeat insert when arrow key used */
- X count = 0;
- X
- X set_want_col = TRUE; /* set Curswant in case of K_DARROW or K_UARROW */
- X cursupdate(); /* Figure out where the cursor is based on Curpos. */
- X setcursor();
- X if (nextc) /* character remaining from CTRL-V */
- X {
- X c = nextc;
- X nextc = 0;
- X }
- X else
- X c = vgetc();
- X
- X#ifdef DIGRAPHS
- X if (p_dg)
- X {
- X if (backspaced)
- X c = getdigraph(backspaced, c);
- X backspaced = 0;
- X if (c == BS && inserted)
- X backspaced = inserted;
- X else
- X inserted = c;
- X }
- X#endif /* DIGRAPHS */
- X
- X if (c == Ctrl('V'))
- X {
- X outchar('^');
- X AppendToRedobuff("\026"); /* CTRL-V */
- X cursupdate();
- X setcursor();
- X
- X c = get_literal(&nextc);
- X
- X /* erase the '^' */
- X if ((cc = gcharCurpos()) == NUL)
- X outchar(' ');
- X else
- X outstrn(transchar(cc));
- X
- X insertchar(c);
- X continue;
- X }
- X switch (c) /* handle character in insert mode */
- X {
- X case Ctrl('O'): /* execute one command */
- X count = 0;
- X restart_edit = TRUE;
- X /*FALLTHROUGH*/
- X
- X case ESC: /* an escape ends input mode */
- X doESCkey:
- X if (!arrow_used)
- X {
- X AppendToRedobuff(ESC_STR);
- X
- X if (--count > 0) /* repeat what was typed */
- X {
- X start_redo_ins();
- X continue;
- X }
- X stop_insert();
- X }
- X set_want_col = TRUE;
- X
- X /*
- X * The cursor should end up on the last inserted character.
- X */
- X if (Curpos.col != 0 && (!restart_edit || gcharCurpos() == NUL))
- X decCurpos();
- X State = NORMAL;
- X script_winsize_pp(); /* may need to put :winsize in script */
- X /* inchar() may have deleted the "INSERT" message */
- X if (Recording)
- X showmode();
- X else if (p_mo)
- X msg("");
- X return;
- X
- X /*
- X * Insert the previously inserted text.
- X * Last_insert actually is a copy of the redo buffer, so we
- X * first have to remove the command.
- X * For ^@ the trailing ESC will end the insert.
- X */
- X case K_ZERO:
- X case Ctrl('A'):
- X stuff_inserted(NUL, 1L, (c == Ctrl('A')));
- X break;
- X
- X /*
- X * insert the contents of a register
- X */
- X case Ctrl('B'):
- X if (!insertbuf(vgetc()))
- X beep();
- X break;
- X
- X /*
- X * If the cursor is on an indent, ^T/^D insert/delete one
- X * shiftwidth. Otherwise ^T/^D behave like a TAB/backspace.
- X * This isn't completely compatible with
- X * vi, but the difference isn't very noticeable and now you can
- X * mix ^D/backspace and ^T/TAB without thinking about which one
- X * must be used.
- X */
- X case Ctrl('T'): /* make indent one shiftwidth greater */
- X case Ctrl('D'): /* make indent one shiftwidth smaller */
- X stop_arrow();
- X AppendToRedobuff(mkstr(c));
- X
- X /* determine offset from first non-blank */
- X temp = Curpos.col;
- X beginline(TRUE);
- X temp -= Curpos.col;
- X
- X shift_line(c == Ctrl('D'));
- X
- X /* try to put cursor on same character */
- X temp += Curpos.col;
- X if (temp <= 0)
- X Curpos.col = 0;
- X else
- X Curpos.col = temp;
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X goto redraw;
- X
- X case BS:
- X case DEL:
- Xnextbs:
- X mode = 0;
- Xdodel:
- X /* can't backup past first character in buffer */
- X /* can't backup past starting point unless "backspace" > 1 */
- X /* can backup to a previous line if "backspace" == 0 */
- X if ((Curpos.lnum == 1 && Curpos.col <= 0) ||
- X (p_bs < 2 && (arrow_used ||
- X (Curpos.lnum == Insstart.lnum &&
- X Curpos.col <= Insstart.col) ||
- X (Curpos.col <= 0 && p_bs == 0))))
- X {
- X beep();
- X goto redraw;
- X }
- X
- X stop_arrow();
- X if (Curpos.col <= 0) /* delete newline! */
- X {
- X if (Curpos.lnum == Insstart.lnum)
- X {
- X if (!u_save((linenr_t)(Curpos.lnum - 2), (linenr_t)(Curpos.lnum + 1)))
- X goto redraw;
- X --Insstart.lnum;
- X Insstart.col = 0;
- X }
- X /* in replace mode with 'repdel' off we only move the cursor */
- X if (State != REPLACE || p_rd)
- X {
- X temp = gcharCurpos(); /* remember current char */
- X --Curpos.lnum;
- X dojoin(FALSE);
- X if (temp == NUL && gcharCurpos() != NUL)
- X ++Curpos.col;
- X }
- X else
- X decCurpos();
- X did_ai = FALSE;
- X }
- X else
- X {
- X /* delete upto starting point, start of line or previous word */
- X do
- X {
- X decCurpos();
- X /* start of word? */
- X if (mode == 1 && !isspace(gcharCurpos()))
- X {
- X mode = 2;
- X temp = isidchar(gcharCurpos());
- X }
- X /* end of word? */
- X if (mode == 2 && isidchar(gcharCurpos()) != temp)
- X {
- X incCurpos();
- X break;
- X }
- X if (State != REPLACE || p_rd)
- X delchar(TRUE);
- X if (mode == 0) /* just a single backspace */
- X break;
- X } while (Curpos.col > 0 && (Curpos.lnum != Insstart.lnum ||
- X Curpos.col != Insstart.col));
- X }
- X did_si = FALSE;
- X can_si = FALSE;
- X if (Curpos.col <= 1)
- X did_ai = FALSE;
- X /*
- X * It's a little strange to put backspaces into the redo
- X * buffer, but it makes auto-indent a lot easier to deal
- X * with.
- X */
- X AppendToRedobuff(mkstr(c));
- X if (vpeekc() == BS)
- X {
- X c = vgetc();
- X goto nextbs; /* speedup multiple backspaces */
- X }
- Xredraw:
- X cursupdate();
- X updateline();
- X break;
- X
- X case Ctrl('W'):
- X /* delete word before cursor */
- X mode = 1;
- X goto dodel;
- X
- X case Ctrl('U'):
- X mode = 3;
- X goto dodel;
- X
- X case K_LARROW:
- X if (oneleft())
- X start_arrow();
- X else
- X beep();
- X break;
- X
- X case K_SLARROW:
- X if (Curpos.lnum > 1 || Curpos.col > 0)
- X {
- X bck_word(1L, 0);
- X start_arrow();
- X }
- X else
- X beep();
- X break;
- X
- X case K_RARROW:
- X if (gcharCurpos() != NUL)
- X {
- X set_want_col = TRUE;
- X start_arrow();
- X ++Curpos.col;
- X }
- X else
- X beep();
- X break;
- X
- X case K_SRARROW:
- X if (Curpos.lnum < line_count || gcharCurpos() != NUL)
- X {
- X fwd_word(1L, 0);
- X start_arrow();
- X }
- X else
- X beep();
- X break;
- X
- X case K_UARROW:
- X if (oneup(1L))
- X start_arrow();
- X else
- X beep();
- X break;
- X
- X case K_SUARROW:
- X if (onepage(BACKWARD, 1L))
- X start_arrow();
- X else
- X beep();
- X break;
- X
- X case K_DARROW:
- X if (onedown(1L))
- X start_arrow();
- X else
- X beep();
- X break;
- X
- X case K_SDARROW:
- X if (onepage(FORWARD, 1L))
- X start_arrow();
- X else
- X beep();
- X break;
- X
- X case TAB:
- X if (!p_et)
- X goto normalchar;
- X /* expand a tab into spaces */
- X stop_arrow();
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X insstr(" " + 16 - (p_ts - Curpos.col % p_ts));
- X AppendToRedobuff("\t");
- X goto redraw;
- X
- X case CR:
- X case NL:
- X stop_arrow();
- X if (State == REPLACE) /* DMT added, 12/89 */
- X delchar(FALSE);
- X AppendToRedobuff(NL_STR);
- X if (!Opencmd(FORWARD, TRUE))
- X goto doESCkey; /* out of memory */
- X break;
- X
- X#ifdef DIGRAPHS
- X case Ctrl('K'):
- X outchar('?');
- X AppendToRedobuff("\026"); /* CTRL-V */
- X setcursor();
- X c = vgetc();
- X outstrn(transchar(c));
- X setcursor();
- X c = getdigraph(c, vgetc());
- X goto normalchar;
- X#endif /* DIGRAPHS */
- X
- X case Ctrl('R'):
- X /*
- X * addition by mool: copy from previous line
- X */
- X lnum = Curpos.lnum - 1;
- X goto copychar;
- X
- X case Ctrl('E'):
- X lnum = Curpos.lnum + 1;
- Xcopychar:
- X if (lnum < 1 || lnum > line_count)
- X {
- X beep();
- X break;
- X }
- X
- X /* try to advance to the cursor column */
- X temp = 0;
- X ptr = (u_char *)nr2ptr(lnum);
- X while (temp < Cursvcol && *ptr)
- X temp += chartabsize(*ptr++, temp);
- X
- X if (temp > Cursvcol)
- X --ptr;
- X if ((c = *ptr) == NUL)
- X {
- X beep();
- X break;
- X }
- X
- X /*FALLTHROUGH*/
- X default:
- Xnormalchar:
- X if (Curpos.col > 0 && ((can_si && c == '}') || (did_si && c == '{')))
- X shift_line(TRUE);
- X insertchar(c);
- X break;
- X }
- X }
- X}
- X
- X/*
- X * Next character is interpreted literally.
- X * A one, two or three digit decimal number is interpreted as its byte value.
- X * If one or two digits are entered, *nextc is set to the next character.
- X */
- X int
- Xget_literal(nextc)
- X int *nextc;
- X{
- X u_char cc;
- X u_char nc;
- X int oldstate;
- X int i;
- X
- X oldstate = State;
- X State = NOMAPPING; /* next characters not mapped */
- X
- X cc = 0;
- X for (i = 0; i < 3; ++i)
- X {
- X nc = vgetc();
- X if (!isdigit(nc))
- X break;
- X cc = cc * 10 + nc - '0';
- X nc = 0;
- X }
- X if (i == 0) /* no number entered */
- X {
- X cc = nc;
- X nc = 0;
- X }
- X else if (cc == 0) /* NUL is stored as NL */
- X cc = '\n';
- X
- X State = oldstate;
- X *nextc = nc;
- X return cc;
- X}
- X
- X/*
- X * Special characters in this context are those that need processing other
- X * than the simple insertion that can be performed here. This includes ESC
- X * which terminates the insert, and CR/NL which need special processing to
- X * open up a new line. This routine tries to optimize insertions performed by
- X * the "redo", "undo" or "put" commands, so it needs to know when it should
- X * stop and defer processing to the "normal" mechanism.
- X */
- X#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL)
- X
- X void
- Xinsertchar(c)
- X unsigned c;
- X{
- X int must_redraw = FALSE;
- X
- X stop_arrow();
- X /*
- X * If the cursor is past 'textwidth' and we are inserting a non-space,
- X * try to break the line in two or more pieces. If c == NUL then we have
- X * been called to do formatting only.
- X */
- X if (c == NUL || !isspace(c))
- X {
- X while (Cursvcol >= p_tw)
- X {
- X int startcol; /* Cursor column at entry */
- X int wantcol; /* column at textwidth border */
- X int foundcol; /* column for start of word */
- X int mincol; /* minimum column for break */
- X
- X if ((startcol = Curpos.col) == 0)
- X break;
- X coladvance((int)p_tw); /* find column of textwidth border */
- X wantcol = Curpos.col;
- X beginline((int)p_ai); /* find start of text */
- X mincol = Curpos.col;
- X
- X Curpos.col = startcol - 1;
- X foundcol = 0;
- X while (Curpos.col > mincol) /* find position to break at */
- X {
- X if (isspace(gcharCurpos()))
- X {
- X foundcol = Curpos.col + 1;
- X while (Curpos.col > 1 && isspace(gcharCurpos()))
- X --Curpos.col;
- X if (Curpos.col < wantcol)
- X break;
- X }
- X --Curpos.col;
- X }
- X
- X if (foundcol == 0) /* no spaces, cannot break line */
- X {
- X Curpos.col = startcol;
- X break;
- X }
- X Curpos.col = foundcol;
- X startcol -= Curpos.col;
- X Opencmd(FORWARD, FALSE);
- X Curpos.col += startcol;
- X curs_columns(); /* update Cursvcol */
- X must_redraw = TRUE;
- X }
- X if (c == NUL) /* formatting only */
- X return;
- X if (must_redraw)
- X updateScreen(CURSUPD);
- X }
- X
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X
- X /*
- X * If there's any pending input, grab up to MAX_COLUMNS at once.
- X * This speeds up normal text input considerably.
- X */
- X if (vpeekc() != NUL && State != REPLACE)
- X {
- X char p[MAX_COLUMNS + 1];
- X int i;
- X
- X p[0] = c;
- X i = 1;
- X while ((c = vpeekc()) != NUL && !ISSPECIAL(c) && i < MAX_COLUMNS &&
- X (Cursvcol += charsize(p[i - 1])) < p_tw)
- X p[i++] = vgetc();
- X p[i] = '\0';
- X insstr(p);
- X AppendToRedobuff(p);
- X }
- X else
- X {
- X inschar(c);
- X AppendToRedobuff(mkstr(c));
- X }
- X
- X updateline();
- X}
- X
- X
- X/*
- X * start_arrow() is called when an arrow key is used in insert mode.
- X * It resembles hitting the <ESC> key.
- X */
- X static void
- Xstart_arrow()
- X{
- X if (!arrow_used) /* something has been inserted */
- X {
- X AppendToRedobuff(ESC_STR);
- X arrow_used = TRUE; /* this means we stopped the current insert */
- X stop_insert();
- X }
- X}
- X
- X/*
- X * stop_arrow() is called before a change is made in insert mode.
- X * If an arrow key has been used, start a new insertion.
- X */
- X static void
- Xstop_arrow()
- X{
- X if (arrow_used)
- X {
- X u_saveCurpos(); /* errors are ignored! */
- X Insstart = Curpos; /* new insertion starts here */
- X ResetBuffers();
- X AppendToRedobuff("1i"); /* pretend we start an insertion */
- X arrow_used = FALSE;
- X }
- X}
- X
- X/*
- X * do a few things to stop inserting
- X */
- X static void
- Xstop_insert()
- X{
- X stop_redo_ins();
- X
- X /*
- X * save the inserted text for later redo with ^@
- X */
- X free(last_insert);
- X last_insert = get_inserted();
- X last_insert_skip = new_insert_skip;
- X
- X /*
- X * If we just did an auto-indent, truncate the line, and put
- X * the cursor back.
- X */
- X if (did_ai && !arrow_used)
- X {
- X *nr2ptr(Curpos.lnum) = NUL;
- X canincrease(0);
- X Curpos.col = 0;
- X }
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X}
- X
- X/*
- X * oneright oneleft onedown oneup
- X *
- X * Move one char {right,left,down,up}. Return TRUE when sucessful, FALSE when
- X * we hit a boundary (of a line, or the file).
- X */
- X
- X int
- Xoneright()
- X{
- X char *ptr;
- X
- X ptr = pos2ptr(&Curpos);
- X set_want_col = TRUE;
- X
- X if (*ptr++ == NUL || *ptr == NUL)
- X return FALSE;
- X ++Curpos.col;
- X return TRUE;
- X}
- X
- X int
- Xoneleft()
- X{
- X set_want_col = TRUE;
- X
- X if (Curpos.col == 0)
- X return FALSE;
- X --Curpos.col;
- X return TRUE;
- X}
- X
- X void
- Xbeginline(flag)
- X int flag;
- X{
- X Curpos.col = 0;
- X if (flag)
- X {
- X register char *ptr;
- X
- X for (ptr = nr2ptr(Curpos.lnum); isspace(*ptr); ++ptr)
- X ++Curpos.col;
- X }
- X set_want_col = TRUE;
- X}
- X
- X int
- Xoneup(n)
- X long n;
- X{
- X if (n != 0 && Curpos.lnum == 1)
- X return FALSE;
- X if (n >= Curpos.lnum)
- X Curpos.lnum = 1;
- X else
- X Curpos.lnum -= n;
- X
- X if (operator == NOP)
- X cursupdate(); /* make sure Topline is valid */
- X
- X /* try to advance to the column we want to be at */
- X coladvance(Curswant);
- X return TRUE;
- X}
- X
- X int
- Xonedown(n)
- X long n;
- X{
- X if (n != 0 && Curpos.lnum == line_count)
- X return FALSE;
- X Curpos.lnum += n;
- X if (Curpos.lnum > line_count)
- X Curpos.lnum = line_count;
- X
- X if (operator == NOP)
- X cursupdate(); /* make sure Topline is valid */
- X
- X /* try to advance to the column we want to be at */
- X coladvance(Curswant);
- X return TRUE;
- X}
- X
- X int
- Xonepage(dir, count)
- X int dir;
- X long count;
- X{
- X linenr_t lp;
- X long n;
- X
- X if (line_count == 1) /* nothing to do */
- X return FALSE;
- X for ( ; count > 0; --count)
- X {
- X if (dir == FORWARD ? (Topline >= line_count - 1) : (Topline == 1))
- X {
- X beep();
- X return FALSE;
- X }
- X lp = Topline;
- X n = 0;
- X if (dir == BACKWARD)
- X {
- X if (lp < line_count)
- X ++lp;
- X Curpos.lnum = lp;
- X }
- X while (n < Rows - 1 && lp >= 1 && lp <= line_count)
- X {
- X n += plines(lp);
- X lp += dir;
- X }
- X if (dir == FORWARD)
- X {
- X if (--lp > 1)
- X --lp;
- X Topline = Curpos.lnum = lp;
- X }
- X else
- X Topline = lp + 1;
- X }
- X beginline(TRUE);
- X updateScreen(VALID);
- X return TRUE;
- X}
- X
- X void
- Xstuff_inserted(c, count, no_esc)
- X int c;
- X long count;
- X int no_esc;
- X{
- X u_char *esc_ptr = NULL;
- X u_char *ptr;
- X
- X if (last_insert == NULL)
- X {
- X beep();
- X return;
- X }
- X if (c)
- X stuffReadbuff(mkstr(c));
- X if (no_esc && (esc_ptr = (u_char *)strrchr((char *)last_insert, 27)) != NULL)
- X *esc_ptr = NUL; /* remove the ESC */
- X
- X /* skip the command */
- X ptr = last_insert + last_insert_skip;
- X
- X do
- X stuffReadbuff((char *)ptr);
- X while (--count > 0);
- X
- X if (no_esc && esc_ptr)
- X *esc_ptr = 27; /* put the ESC back */
- X}
- END_OF_FILE
- if test 16324 -ne `wc -c <'vim/src/edit.c'`; then
- echo shar: \"'vim/src/edit.c'\" unpacked with wrong size!
- fi
- # end of 'vim/src/edit.c'
- fi
- if test -f 'vim/src/param.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vim/src/param.c'\"
- else
- echo shar: Extracting \"'vim/src/param.c'\" \(16498 characters\)
- sed "s/^X//" >'vim/src/param.c' <<'END_OF_FILE'
- X/* vi:ts=4:sw=4
- X *
- X * VIM - Vi IMitation
- X *
- X * Code Contributions By: Bram Moolenaar mool@oce.nl
- X * Tim Thompson twitch!tjt
- X * Tony Andrews onecom!wldrdg!tony
- X * G. R. (Fred) Walter watmath!watcgl!grwalter
- X */
- X
- X/*
- X * Code to handle user-settable parameters. This is all pretty much table-
- X * driven. To add a new parameter, put it in the params array, and add a
- X * variable for it in param.h. If it's a numeric parameter, add any necessary
- X * bounds checks to doset().
- X */
- X
- X#include "vim.h"
- X#include "globals.h"
- X#include "proto.h"
- X#include "param.h"
- X
- Xstruct param
- X{
- X char *fullname; /* full parameter name */
- X char *shortname; /* permissible abbreviation */
- X int flags; /* see below */
- X char *var; /* pointer to variable */
- X};
- X
- X/*
- X * Flags
- X */
- X#define P_BOOL 0x01 /* the parameter is boolean */
- X#define P_NUM 0x02 /* the parameter is numeric */
- X#define P_STRING 0x04 /* the parameter is a string */
- X#define P_CHANGED 0x08 /* the parameter has been changed */
- X
- X/*
- X * The param structure is initialized here.
- X * The order of the parameters should be alfabetic
- X */
- Xstruct param params[] =
- X{
- X {"autoindent", "ai", P_BOOL, (char *)&p_ai},
- X/* {"autoprint", "ap", P_BOOL, (char *)&p_ap}, */
- X {"autowrite", "aw", P_BOOL, (char *)&p_aw},
- X {"backspace", "bs", P_NUM, (char *)&p_bs},
- X {"backup", "bk", P_BOOL, (char *)&p_bk},
- X#ifdef UNIX
- X {"backupdir", "bdir", P_STRING, (char *)&p_bdir},
- X#endif
- X/* {"beautify", "bf", P_BOOL, (char *)&p_bf}, */
- X {"columns", "co", P_NUM, (char *)&Columns},
- X {"compatible", "cp", P_BOOL, (char *)&p_cp},
- X#ifdef DIGRAPHS
- X {"digraph", "dg", P_BOOL, (char *)&p_dg},
- X#endif /* DIGRAPHS */
- X {"directory", "dir", P_STRING, (char *)&p_dir},
- X {"equalprg", "ep", P_STRING, (char *)&p_ep},
- X {"errorbells", "eb", P_BOOL, (char *)&p_eb},
- X {"errorfile", "ef", P_STRING, (char *)&p_ef},
- X {"expandtab", "et", P_BOOL, (char *)&p_et},
- X {"graphic", "gr", P_BOOL, (char *)&p_gr},
- X/* {"hardtabs", "ht", P_NUM, (char *)&p_ht}, */
- X {"helpfile", "hf", P_STRING, (char *)&p_hf},
- X {"history", "hi", P_NUM, (char *)&p_hi},
- X {"ignorecase", "ic", P_BOOL, (char *)&p_ic},
- X {"insertmode", "im", P_BOOL, (char *)&p_im},
- X {"joinspaces", "js", P_BOOL, (char *)&p_js},
- X {"keywordprg", "kp", P_STRING, (char *)&p_kp},
- X {"lines", NULL, P_NUM, (char *)&Rows},
- X/* {"lisp", NULL, P_BOOL (char *)&p_lisp}, */
- X {"list", NULL, P_BOOL, (char *)&p_list},
- X {"magic", NULL, P_BOOL, (char *)&p_magic},
- X {"modelines", "ml", P_NUM, (char *)&p_ml},
- X {"number", "nu", P_BOOL, (char *)&p_nu},
- X/* {"open", NULL, P_BOOL, (char *)&p_open}, */
- X/* {"optimize", "opt", P_BOOL, (char *)&p_opt}, */
- X {"paragraphs", "para", P_STRING, (char *)&p_para},
- X/* {"prompt", NULL, P_BOOL, (char *)&p_prompt}, */
- X {"readonly", "ro", P_BOOL, (char *)&p_ro},
- X/* {"redraw", NULL, P_BOOL, (char *)&p_redraw}, */
- X {"remap", NULL, P_BOOL, (char *)&p_remap},
- X {"repdel", "rd", P_BOOL, (char *)&p_rd},
- X {"report", NULL, P_NUM, (char *)&p_report},
- X {"ruler", "ru", P_BOOL, (char *)&p_ru},
- X {"scroll", NULL, P_NUM, (char *)&p_scroll},
- X {"scrolljump", "sj", P_NUM, (char *)&p_sj},
- X {"sections", NULL, P_STRING, (char *)&p_sections},
- X {"shell", "sh", P_STRING, (char *)&p_sh},
- X {"shelltype", "st", P_NUM, (char *)&p_st},
- X {"shiftround", "sr", P_BOOL, (char *)&p_sr},
- X {"shiftwidth", "sw", P_NUM, (char *)&p_sw},
- X#ifndef MSDOS
- X {"shortname", "sn", P_BOOL, (char *)&p_sn},
- X#endif
- X {"showcmd", "sc", P_BOOL, (char *)&p_sc},
- X {"showmatch", "sm", P_BOOL, (char *)&p_sm},
- X {"showmode", "mo", P_BOOL, (char *)&p_mo},
- X/* {"slowopen", "slow", P_BOOL, (char *)&p_slow}, */
- X {"smartindent", "si", P_BOOL, (char *)&p_si},
- X {"suffixes", "su", P_STRING, (char *)&p_su},
- X {"tabstop", "ts", P_NUM, (char *)&p_ts},
- X {"taglength", "tl", P_NUM, (char *)&p_tl},
- X {"tags", NULL, P_STRING, (char *)&p_tags},
- X {"term", NULL, P_STRING, (char *)&term_strings.t_name},
- X {"terse", NULL, P_BOOL, (char *)&p_terse},
- X#ifdef MSDOS
- X {"textmode", "tx", P_BOOL, (char *)&p_tx},
- X#endif
- X {"textwidth", "tw", P_NUM, (char *)&p_tw},
- X {"tildeop", "to", P_BOOL, (char *)&p_to},
- X {"timeout", NULL, P_BOOL, (char *)&p_timeout},
- X {"ttimeout", NULL, P_BOOL, (char *)&p_ttimeout},
- X {"undolevels", "ul", P_NUM, (char *)&p_ul},
- X {"updatecount", "uc", P_NUM, (char *)&p_uc},
- X {"updatetime", "ut", P_NUM, (char *)&p_ut},
- X {"visualbell", "vb", P_BOOL, (char *)&p_vb},
- X {"warn", NULL, P_BOOL, (char *)&p_warn},
- X/* {"window", NULL, P_NUM, (char *)&p_window}, */
- X/* {"w300", NULL, P_NUM, (char *)&p_w300}, */
- X/* {"w1200", NULL, P_NUM, (char *)&p_w1200}, */
- X/* {"w9600", NULL, P_NUM, (char *)&p_w9600}, */
- X {"wrapscan", "ws", P_BOOL, (char *)&p_ws},
- X {"wrapmargin", "wm", P_NUM, (char *)&p_wm},
- X {"writeany", "wa", P_BOOL, (char *)&p_wa},
- X {"writebackup", "wb", P_BOOL, (char *)&p_wb},
- X {"yankendofline", "ye", P_BOOL, (char *)&p_ye},
- X
- X/* terminal output codes */
- X {"t_el", NULL, P_STRING, (char *)&term_strings.t_el},
- X {"t_il", NULL, P_STRING, (char *)&term_strings.t_il},
- X {"t_cil", NULL, P_STRING, (char *)&term_strings.t_cil},
- X {"t_dl", NULL, P_STRING, (char *)&term_strings.t_dl},
- X {"t_cdl", NULL, P_STRING, (char *)&term_strings.t_cdl},
- X {"t_ed", NULL, P_STRING, (char *)&term_strings.t_ed},
- X {"t_ci", NULL, P_STRING, (char *)&term_strings.t_ci},
- X {"t_cv", NULL, P_STRING, (char *)&term_strings.t_cv},
- X {"t_tp", NULL, P_STRING, (char *)&term_strings.t_tp},
- X {"t_ti", NULL, P_STRING, (char *)&term_strings.t_ti},
- X {"t_cm", NULL, P_STRING, (char *)&term_strings.t_cm},
- X {"t_sr", NULL, P_STRING, (char *)&term_strings.t_sr},
- X {"t_cri", NULL, P_STRING, (char *)&term_strings.t_cri},
- X {"t_vb", NULL, P_STRING, (char *)&term_strings.t_vb},
- X {"t_ks", NULL, P_STRING, (char *)&term_strings.t_ks},
- X {"t_ke", NULL, P_STRING, (char *)&term_strings.t_ke},
- X {"t_ts", NULL, P_STRING, (char *)&term_strings.t_ts},
- X {"t_te", NULL, P_STRING, (char *)&term_strings.t_te},
- X
- X/* terminal key codes */
- X {"t_ku", NULL, P_STRING, (char *)&term_strings.t_ku},
- X {"t_kd", NULL, P_STRING, (char *)&term_strings.t_kd},
- X {"t_kr", NULL, P_STRING, (char *)&term_strings.t_kr},
- X {"t_kl", NULL, P_STRING, (char *)&term_strings.t_kl},
- X {"t_sku", NULL, P_STRING, (char *)&term_strings.t_sku},
- X {"t_skd", NULL, P_STRING, (char *)&term_strings.t_skd},
- X {"t_skr", NULL, P_STRING, (char *)&term_strings.t_skr},
- X {"t_skl", NULL, P_STRING, (char *)&term_strings.t_skl},
- X {"t_f1", NULL, P_STRING, (char *)&term_strings.t_f1},
- X {"t_f2", NULL, P_STRING, (char *)&term_strings.t_f2},
- X {"t_f3", NULL, P_STRING, (char *)&term_strings.t_f3},
- X {"t_f4", NULL, P_STRING, (char *)&term_strings.t_f4},
- X {"t_f5", NULL, P_STRING, (char *)&term_strings.t_f5},
- X {"t_f6", NULL, P_STRING, (char *)&term_strings.t_f6},
- X {"t_f7", NULL, P_STRING, (char *)&term_strings.t_f7},
- X {"t_f8", NULL, P_STRING, (char *)&term_strings.t_f8},
- X {"t_f9", NULL, P_STRING, (char *)&term_strings.t_f9},
- X {"t_f10", NULL, P_STRING, (char *)&term_strings.t_f10},
- X {"t_sf1", NULL, P_STRING, (char *)&term_strings.t_sf1},
- X {"t_sf2", NULL, P_STRING, (char *)&term_strings.t_sf2},
- X {"t_sf3", NULL, P_STRING, (char *)&term_strings.t_sf3},
- X {"t_sf4", NULL, P_STRING, (char *)&term_strings.t_sf4},
- X {"t_sf5", NULL, P_STRING, (char *)&term_strings.t_sf5},
- X {"t_sf6", NULL, P_STRING, (char *)&term_strings.t_sf6},
- X {"t_sf7", NULL, P_STRING, (char *)&term_strings.t_sf7},
- X {"t_sf8", NULL, P_STRING, (char *)&term_strings.t_sf8},
- X {"t_sf9", NULL, P_STRING, (char *)&term_strings.t_sf9},
- X {"t_sf10", NULL, P_STRING, (char *)&term_strings.t_sf10},
- X {"t_help", NULL, P_STRING, (char *)&term_strings.t_help},
- X {"t_undo", NULL, P_STRING, (char *)&term_strings.t_undo},
- X {NULL, NULL, 0, NULL} /* end marker */
- X};
- X
- Xstatic void showparams __ARGS((int));
- Xstatic void showonep __ARGS((struct param *));
- Xstatic int istermparam __ARGS((struct param *));
- X
- X/*
- X * Initialize the shell parameter and scroll size.
- X */
- X void
- Xset_init()
- X{
- X char *p;
- X
- X if ((p = (char *)vimgetenv("SHELL")) != NULL)
- X p_sh = strsave(p);
- X p_scroll = (Rows >> 1);
- X}
- X
- X void
- Xdoset(arg)
- X char *arg; /* parameter string */
- X{
- X register int i;
- X char *s;
- X char *errmsg;
- X char *startarg;
- X int prefix; /* 0: nothing, 1: "no", 2: "inv" in front of name */
- X int nextchar;
- X int len = 0;
- X int flags;
- X int olduc = p_uc; /* remember old update count */
- X
- X if (*arg == NUL)
- X {
- X showparams(0);
- X return;
- X }
- X
- X while (*arg) /* loop to process all parameters */
- X {
- X errmsg = NULL;
- X startarg = arg; /* remember for error message */
- X if (strncmp(arg, "all", (size_t)3) == 0)
- X showparams(1);
- X else if (strncmp(arg, "termcap", (size_t)7) == 0)
- X showparams(2);
- X else
- X {
- X prefix = 1;
- X if (strncmp(arg, "no", (size_t)2) == 0)
- X {
- X prefix = 0;
- X arg += 2;
- X }
- X else if (strncmp(arg, "inv", (size_t)3) == 0)
- X {
- X prefix = 2;
- X arg += 3;
- X }
- X for (i = 0; (s = params[i].fullname) != NULL; i++)
- X {
- X if (strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match full name */
- X break;
- X }
- X if (s == NULL)
- X {
- X for (i = 0; params[i].fullname != NULL; i++)
- X {
- X s = params[i].shortname;
- X if (s != NULL && strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match short name */
- X break;
- X s = NULL;
- X }
- X }
- X
- X if (s == NULL) /* found a mismatch: skip the rest */
- X {
- X errmsg = "Unknown option: "; /* must be 18 chars */
- X goto skip;
- X }
- X
- X flags = params[i].flags;
- X nextchar = arg[len];
- X /*
- X * allow '=' and ':' as MSDOS command.com allows only one
- X * '=' character per "set" command line. grrr. (jw)
- X */
- X if (nextchar == '?' ||
- X (prefix == 1 && nextchar != '=' &&
- X nextchar != ':' && !(flags & P_BOOL)))
- X { /* print value */
- X gotocmdline(TRUE, NUL);
- X showonep(¶ms[i]);
- X }
- X else if (nextchar != NUL && strchr("=: \t", nextchar) == NULL)
- X {
- X errmsg = e_setarg;
- X goto skip;
- X }
- X else if (flags & P_BOOL) /* boolean */
- X {
- X if (nextchar == '=' || nextchar == ':')
- X {
- X errmsg = e_setarg;
- X goto skip;
- X }
- X if (prefix == 2)
- X *(int *)(params[i].var) ^= 1; /* invert it */
- X else
- X *(int *)(params[i].var) = prefix;
- X if ((int *)params[i].var == &p_cp && p_cp) /* handle cp here */
- X {
- X p_bs = 0; /* normal backspace */
- X p_bk = 0; /* no backup file */
- X#ifdef DIGRAPHS
- X p_dg = 0; /* no digraphs */
- X#endif /* DIGRAPHS */
- X p_et = 0; /* no expansion of tabs */
- X p_hi = 0; /* no history */
- X p_im = 0; /* do not start in insert mode */
- X p_js = 1; /* insert 2 spaces after period */
- X p_ml = 0; /* no modelines */
- X p_rd = 1; /* del replaces char */
- X p_ru = 0; /* no ruler */
- X p_sj = 1; /* no scrolljump */
- X p_sr = 0; /* do not round indent to shiftwidth */
- X p_sc = 0; /* no showcommand */
- X p_mo = 0; /* no showmode */
- X p_si = 0; /* no smartindent */
- X p_tw = 9999; /* maximum textwidth */
- X p_to = 0; /* no tilde operator */
- X p_ttimeout = 0; /* no terminal timeout */
- X p_ul = 0; /* no multilevel undo */
- X p_uc = 0; /* no autoscript file */
- X p_wb = 0; /* no backup file */
- X p_ye = 0; /* no yank to end of line */
- X }
- X }
- X else /* numeric or string */
- X {
- X if ((nextchar != '=' && nextchar != ':') || prefix != 1)
- X {
- X errmsg = e_setarg;
- X goto skip;
- X }
- X if (flags & P_NUM) /* numeric */
- X {
- X len = atoi(arg + len + 1);
- X if ((long *)params[i].var == &p_wm) /* wrapmargin is translated into textlength */
- X {
- X if (len >= Columns)
- X len = Columns - 1;
- X p_tw = Columns - len;
- X }
- X *(long *)(params[i].var) = len;
- X }
- X else /* string */
- X {
- X arg += len + 1;
- X s = alloc((unsigned)(strlen(arg) + 1)); /* get a bit too much */
- X if (s == NULL)
- X break;
- X if (flags & P_CHANGED)
- X free(*(char **)(params[i].var));
- X *(char **)(params[i].var) = s;
- X /* copy the string */
- X while (*arg && *arg != ' ' && *arg != '\t')
- X {
- X if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */
- X ++arg;
- X *s++ = *arg++;
- X }
- X *s = NUL;
- X /*
- X * options that need some action
- X * to perform when changed (jw)
- X */
- X if (params[i].var == (char *)&term_strings.t_name)
- X set_term(term_strings.t_name);
- X else if (istermparam(¶ms[i]))
- X ttest(FALSE);
- X }
- X }
- X params[i].flags |= P_CHANGED;
- X }
- X
- Xskip:
- X if (errmsg)
- X {
- X strcpy(IObuff, errmsg);
- X s = IObuff + 18;
- X while (*startarg && !isspace(*startarg))
- X *s++ = *startarg++;
- X *s = NUL;
- X emsg(IObuff);
- X arg = startarg; /* skip to next argument */
- X }
- X
- X skiptospace(&arg); /* skip to next white space */
- X skipspace(&arg); /* skip spaces */
- X }
- X
- X /*
- X * Check the bounds for numeric parameters here
- X */
- X if (Rows < 2)
- X {
- X Rows = 2;
- X emsg("Need at least 2 lines");
- X }
- X if (p_ts <= 0 || p_ts > 16)
- X {
- X emsg(e_tabsize);
- X p_ts = 8;
- X }
- X if (p_scroll <= 0 || p_scroll > Rows)
- X {
- X emsg(e_scroll);
- X p_scroll = Rows >> 1;
- X }
- X if (p_report < 0)
- X {
- X emsg(e_positive);
- X p_report = 1;
- X }
- X if (p_sj < 0 || p_sj >= Rows)
- X {
- X emsg(e_scroll);
- X p_sj = 1;
- X }
- X if (p_ul < 0)
- X {
- X emsg(e_positive);
- X p_ul = 100;
- X }
- X if (p_uc < 0)
- X {
- X emsg(e_positive);
- X p_uc = 100;
- X }
- X if (p_uc == 0 && olduc != 0) /* p_uc changed from on to off */
- X stopscript();
- X if (p_uc > 0 && olduc == 0) /* p_uc changed from off to on */
- X startscript();
- X#ifdef MSDOS
- X textfile(p_tx);
- X#endif
- X if (p_ut < 0)
- X {
- X emsg(e_positive);
- X p_ut = 2000;
- X }
- X
- X /*
- X * Update the screen in case we changed something like "tabstop" or
- X * "lines" or "list" that will change its appearance.
- X */
- X updateScreen(NOT_VALID);
- X}
- X
- X/*
- X * if 'all' == 0: show changed parameters
- X * if 'all' == 1: show all normal parameters
- X * if 'all' == 2: show all terminal parameters
- X */
- X static void
- Xshowparams(all)
- X int all;
- X{
- X struct param *p;
- X int col = 0;
- X int inc;
- X int isterm;
- X
- X gotocmdline(TRUE, NUL);
- X outstrn("Parameters:\n");
- X
- X#ifdef AMIGA
- X settmode(0); /* set cooked mode so output can be halted */
- X#endif
- X for (p = ¶ms[0]; p->fullname != NULL; p++)
- X {
- X isterm = istermparam(p);
- X if ((all == 2 && isterm) ||
- X (all == 1 && !isterm) ||
- X (all == 0 && (p->flags & P_CHANGED)))
- X {
- X if ((p->flags & P_STRING) && *(char **)(p->var) != NULL)
- X inc = strlen(p->fullname) + strsize(*(char **)(p->var)) + 1;
- X else
- X inc = 1;
- X if (col + inc >= Columns)
- X {
- X outchar('\n');
- X col = 0;
- X }
- X
- X showonep(p);
- X col += inc;
- X col += 19 - col % 19;
- X if (col < Columns - 19)
- X windgoto((int)Rows - 1, col); /* make columns */
- X else
- X {
- X col = 0;
- X outchar('\n');
- X }
- X flushbuf();
- X }
- X }
- X
- X if (col)
- X outchar('\n');
- X#ifdef AMIGA
- X settmode(1);
- X#endif
- X wait_return(TRUE);
- X}
- X
- X static void
- Xshowonep(p)
- X struct param *p;
- X{
- X char buf[64];
- X
- X if ((p->flags & P_BOOL) && !*(int *)(p->var))
- X outstrn("no");
- X outstrn(p->fullname);
- X if (!(p->flags & P_BOOL))
- X {
- X outchar('=');
- X if (p->flags & P_NUM)
- X {
- X sprintf(buf, "%ld", *(long *)(p->var));
- X outstrn(buf);
- X }
- X else if (*(char **)(p->var) != NULL)
- X outtrans(*(char **)(p->var), -1);
- X }
- X}
- X
- X/*
- X * Write modified parameters as set command to a file.
- X * Return 1 on error.
- X */
- X int
- Xmakeset(fd)
- X FILE *fd;
- X{
- X struct param *p;
- X char *s;
- X int e;
- X
- X for (p = ¶ms[0]; p->fullname != NULL; p++)
- X if (p->flags & P_CHANGED)
- X {
- X if (p->flags & P_BOOL)
- X e = fprintf(fd, "set %s%s\n", *(int *)(p->var) ? "" : "no", p->fullname);
- X else if (p->flags & P_NUM)
- X e = fprintf(fd, "set %s=%ld\n", p->fullname, *(long *)(p->var));
- X else
- X {
- X fprintf(fd, "set %s=", p->fullname);
- X s = *(char **)(p->var);
- X if (s != NULL)
- X for ( ; *s; ++s)
- X {
- X if (*s < ' ' || *s > '~')
- X putc(Ctrl('V'), fd);
- X putc(*s, fd);
- X }
- X e = putc('\n', fd);
- X }
- X if (e < 0)
- X return 1;
- X }
- X return 0;
- X}
- X
- X/*
- X * Clear all the terminal parameters.
- X * If the parameter has been changed, free the allocated memory.
- X * Reset the "changed" flag, so the new value will not be freed.
- X */
- X void
- Xclear_termparam()
- X{
- X struct param *p;
- X
- X for (p = ¶ms[0]; p->fullname != NULL; p++)
- X if (istermparam(p))
- X {
- X if (p->flags & P_CHANGED)
- X free(*(char **)(p->var));
- X *(char **)(p->var) = NULL;
- X p->flags &= ~P_CHANGED;
- X }
- X}
- X
- X static int
- Xistermparam(p)
- X struct param *p;
- X{
- X return (p->fullname[0] == 't' && p->fullname[1] == '_');
- X}
- END_OF_FILE
- if test 16498 -ne `wc -c <'vim/src/param.c'`; then
- echo shar: \"'vim/src/param.c'\" unpacked with wrong size!
- fi
- # end of 'vim/src/param.c'
- fi
- if test -f 'vim/src/unix.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vim/src/unix.c'\"
- else
- echo shar: Extracting \"'vim/src/unix.c'\" \(15625 characters\)
- sed "s/^X//" >'vim/src/unix.c' <<'END_OF_FILE'
- X/* vi:ts=4:sw=4
- X *
- X *
- X * VIM - Vi IMitation
- X *
- X * Code Contributions By: Bram Moolenaar mool@oce.nl
- X * Tim Thompson twitch!tjt
- X * Tony Andrews onecom!wldrdg!tony
- X * G. R. (Fred) Walter watmath!watcgl!grwalter
- X */
- X/*
- X * unix.c -- BSD and SYSV code
- X *
- X * A lot of this file was written by Juergen Weigert.
- X */
- X
- X#include "vim.h"
- X#include "globals.h"
- X#include "param.h"
- X#include "proto.h"
- X
- X#include <fcntl.h>
- X#if !defined(pyr) && !defined(NOT_BOTH_TIME)
- X# include <time.h> /* on some systems time.h should not be
- X included together with sys/time.h */
- X#endif
- X#include <sys/ioctl.h>
- X#ifndef M_XENIX
- X# include <sys/types.h>
- X#endif
- X#include <signal.h>
- X
- X#ifdef SYSV
- X# ifdef M_XENIX
- X# include <sys/select.h>
- X# define bzero(a, b) memset((a), 0, (b))
- X# else
- X# include <poll.h>
- X# endif
- X# include <termio.h>
- X#else /* SYSV */
- X# include <sys/time.h>
- X# ifdef hpux
- X# include <termio.h>
- X# define SIGWINCH SIGWINDOW
- X# else
- X# include <sgtty.h>
- X# endif /* hpux */
- X#endif /* SYSV */
- X
- X#if (defined(pyr) || defined(NO_FD_ZERO)) && defined(SYSV) && defined(FD_ZERO)
- X# undef FD_ZERO
- X#endif
- X
- X#ifdef ESIX
- X# ifdef SIGWINCH
- X# undef SIGWINCH
- X# endif
- X# ifdef TIOCGWINSZ
- X# undef TIOCGWINSZ
- X# endif
- X#endif
- X
- Xstatic int Read __ARGS((char *, long));
- Xstatic int WaitForChar __ARGS((int));
- Xstatic int RealWaitForChar __ARGS((int));
- Xstatic void fill_inbuf __ARGS((void));
- X#if defined(SIGWINCH) && !defined(linux)
- Xstatic void sig_winch __ARGS((int, int, struct sigcontext *));
- X#endif
- X
- Xstatic int do_resize = FALSE;
- X
- X/*
- X * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
- X */
- X#undef TRUE
- X#define TRUE 1
- X#undef FALSE
- X#define FALSE 0
- X
- X/*
- X * the number of calls to Write is reduced by using the buffer "outbuf"
- X */
- X#define BSIZE 2048
- Xstatic u_char outbuf[BSIZE];
- Xstatic int bpos = 0;
- X
- X/*
- X * flushbuf(): flush the output buffer
- X */
- X void
- Xflushbuf()
- X{
- X if (bpos != 0)
- X write(1, (char *)outbuf, (long)bpos);
- X bpos = 0;
- X}
- X
- X/*
- X * outchar(c): put a character into the output buffer. Flush it if it becomes full.
- X */
- X void
- Xoutchar(c)
- X unsigned c;
- X{
- X if (c == '\n') /* turn LF into CR-LF (CRMOD does not seem to do this) */
- X outchar('\r');
- X outbuf[bpos] = c;
- X ++bpos;
- X if (bpos >= BSIZE)
- X flushbuf();
- X}
- X
- X/*
- X * GetChars(): low level input funcion.
- X * Get a characters from the keyboard.
- X * If type == T_PEEK do not wait for characters.
- X * If type == T_WAIT wait a short time for characters.
- X * If type == T_BLOCK wait for characters.
- X */
- X int
- XGetChars(buf, maxlen, type)
- X char *buf;
- X int maxlen;
- X int type;
- X{
- X int len;
- X int time = 1000; /* one second */
- X
- X switch (type)
- X {
- X case T_PEEK:
- X time = 20;
- X case T_WAIT:
- X if (WaitForChar(time) == 0) /* no character available */
- X return 0;
- X break;
- X
- X case T_BLOCK:
- X /*
- X * If there is no character available within 2 seconds (default)
- X * write the autoscript file to disk
- X */
- X if (WaitForChar((int)p_ut) == 0)
- X updatescript(0);
- X }
- X
- X for (;;) /* repeat until we got a character */
- X {
- X /*
- X * we want to be interrupted by the winch signal
- X */
- X WaitForChar(-1);
- X if (do_resize)
- X {
- X debug("do_resize!\n");
- X set_winsize(0, 0, FALSE);
- X do_resize = FALSE;
- X continue;
- X }
- X len = Read(buf, (long)maxlen);
- X if (len > 0)
- X return len;
- X }
- X}
- X
- X void
- Xvim_delay()
- X{
- X#if defined(SYSV) && !defined(M_XENIX)
- X poll(0, 0, 500);
- X#else
- X struct timeval tv;
- X
- X tv.tv_sec = 25 / 50;
- X tv.tv_usec = (25 % 50) * (1000000/50);
- X select(0, 0, 0, 0, &tv);
- X#endif
- X}
- X
- X static void
- Xsig_winch(sig, code, scp)
- X int sig;
- X int code;
- X struct sigcontext *scp;
- X{
- X#if defined(SIGWINCH) && (defined(SYSV) || defined(linux) || defined(hpux))
- X signal(SIGWINCH, sig_winch);
- X#endif
- X do_resize = TRUE;
- X}
- X
- X/*
- X * If the machine has job control, use it to suspend the program,
- X * otherwise fake it by starting a new shell.
- X */
- X void
- Xmch_suspend()
- X{
- X#ifdef SIGTSTP
- X settmode(0);
- X stoptermcap();
- X kill(0, SIGTSTP); /* send ourselves a STOP signal */
- X settmode(1);
- X starttermcap();
- X#else
- X outstr("new shell started\n");
- X stoptermcap();
- X call_shell(NULL, 0);
- X starttermcap();
- X#endif
- X}
- X
- X void
- Xmch_windinit()
- X{
- X Columns = 80;
- X Rows = 24;
- X
- X flushbuf();
- X
- X mch_get_winsize();
- X#if defined(SIGWINCH)
- X signal(SIGWINCH, sig_winch);
- X#endif
- X}
- X
- X/*
- X * Check_win checks whether we have an interactive window.
- X * If not, a new window is opened with the newcli command.
- X * If we would open a window ourselves, the :sh and :! commands would not
- X * work properly (Why? probably because we are then running in a background CLI).
- X * This also is the best way to assure proper working in a next Workbench release.
- X *
- X * For the -e option (quickfix mode) we open our own window and disable :sh.
- X * Otherwise we would never know when editing is finished.
- X */
- X#define BUF2SIZE 320 /* lenght of buffer for argument with complete path */
- X
- X void
- Xcheck_win(argc, argv)
- X int argc;
- X char **argv;
- X{
- X if (!isatty(0) || !isatty(1))
- X {
- X fprintf(stderr, "VIM: no controlling terminal\n");
- X exit(2);
- X }
- X}
- X
- X/*
- X * fname_case(): Set the case of the filename, if it already exists.
- X * This will cause the filename to remain exactly the same.
- X */
- X void
- Xfname_case(name)
- X char *name;
- X{
- X}
- X
- X void
- Xsettitle(str)
- X char *str;
- X{
- X}
- X
- X void
- Xresettitle()
- X{
- X}
- X
- X/*
- X * get name of current directory into buffer 'buf' of length 'len' bytes
- X */
- X int
- Xdirname(buf, len)
- X char *buf;
- X int len;
- X{
- X#if defined(SYSV) || defined(hpux)
- X extern int errno;
- X extern char *sys_errlist[];
- X
- X if (getcwd(buf,len) == NULL)
- X {
- X strcpy(buf, sys_errlist[errno]);
- X return 1;
- X }
- X return 0;
- X#else
- X return (int)getwd(buf);
- X#endif
- X}
- X
- X/*
- X * get absolute filename into buffer 'buf' of length 'len' bytes
- X */
- X int
- XFullName(fname, buf, len)
- X char *fname, *buf;
- X int len;
- X{
- X *buf = 0;
- X#if defined(linux) || defined(UNIX_WITHOUT_AMD)
- X {
- X int l;
- X
- X if (*fname != '/')
- X {
- X#if defined(SYSV) || defined(hpux)
- X (void)getcwd(buf,len);
- X#else
- X (void)getwd(buf);
- X#endif
- X l = strlen(buf);
- X if (l && buf[l-1] != '/')
- X strcat(buf, "/");
- X }
- X }
- X#endif /* UNIX_WITHOUT_AMD */
- X strcat(buf, fname);
- X return 0;
- X}
- X
- X/*
- X * get file permissions for 'name'
- X */
- X long
- Xgetperm(name)
- X char *name;
- X{
- X struct stat statb;
- X
- X if (stat(name, &statb))
- X return -1;
- X return statb.st_mode;
- X}
- X
- X/*
- X * set file permission for 'name' to 'perm'
- X */
- X int
- Xsetperm(name, perm)
- X char *name;
- X int perm;
- X{
- X return chmod(name, perm);
- X}
- X
- X/*
- X * check if "name" is a directory
- X */
- X int
- Xisdir(name)
- X char *name;
- X{
- X struct stat statb;
- X
- X if (stat(name, &statb))
- X return -1;
- X return (statb.st_mode & S_IFMT) != S_IFREG;
- X}
- X
- X void
- Xmch_windexit(r)
- X int r;
- X{
- X settmode(0);
- X stoptermcap();
- X flushbuf();
- X stopscript(); /* remove autoscript file */
- X exit(r);
- X}
- X
- X void
- Xmch_settmode(raw)
- X int raw;
- X{
- X#if defined(ECHOE) && defined(ICANON)
- X /* for "new" tty systems */
- X static struct termio told;
- X struct termio tnew;
- X
- X if (raw)
- X {
- X ioctl(0, TCGETA, &told);
- X tnew = told;
- X tnew.c_iflag &= ~ICRNL; /* enables typing ^V^M */
- X tnew.c_iflag &= ~IXON; /* enables typing ^Q */
- X tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE);
- X tnew.c_cc[VMIN] = 1; /* return after 1 char */
- X tnew.c_cc[VTIME] = 0; /* don't wait */
- X ioctl(0, TCSETA, &tnew);
- X }
- X else
- X ioctl(0, TCSETA, &told);
- X#else
- X# ifndef TIOCSETN
- X# define TIOCSETN TIOCSETP /* for hpux 9.0 */
- X# endif
- X /* for "old" tty systems */
- X static struct sgttyb ttybold;
- X struct sgttyb ttybnew;
- X
- X if (raw)
- X {
- X ioctl(0, TIOCGETP, &ttybold);
- X ttybnew = ttybold;
- X ttybnew.sg_flags &= ~(CRMOD | ECHO);
- X ttybnew.sg_flags |= RAW;
- X ioctl(0, TIOCSETN, &ttybnew);
- X }
- X else
- X ioctl(0, TIOCSETN, &ttybold);
- X#endif
- X}
- X
- X int
- Xmch_get_winsize()
- X{
- X int old_Rows = Rows;
- X int old_Columns = Columns;
- X char *p;
- X
- X Columns = 0;
- X Rows = 0;
- X
- X/*
- X * when called without a signal, get winsize from environment
- X */
- X if (!do_resize)
- X {
- X if ((p = (char *)getenv("LINES")))
- X Rows = atoi(p);
- X if ((p = (char *)getenv("COLUMNS")))
- X Columns = atoi(p);
- X if (Columns <= 0 || Rows <= 0)
- X do_resize = TRUE;
- X }
- X
- X/*
- X * when got a signal, or no size in environment, try using an ioctl
- X */
- X if (do_resize)
- X {
- X# ifdef TIOCGSIZE
- X struct ttysize ts;
- X
- X if (ioctl(0, TIOCGSIZE, &ts) == 0)
- X {
- X if (Columns == 0)
- X Columns = ts.ts_cols;
- X if (Rows == 0)
- X Rows = ts.ts_lines;
- X }
- X# else /* TIOCGSIZE */
- X# ifdef TIOCGWINSZ
- X struct winsize ws;
- X
- X if (ioctl(0, TIOCGWINSZ, &ws) == 0)
- X {
- X if (Columns == 0)
- X Columns = ws.ws_col;
- X if (Rows == 0)
- X Rows = ws.ws_row;
- X }
- X# endif /* TIOCGWINSZ */
- X# endif /* TIOCGSIZE */
- X do_resize = FALSE;
- X }
- X
- X#ifdef TERMCAP
- X/*
- X * if previous work fails, try reading the termcap
- X */
- X if (Columns == 0 || Rows == 0)
- X {
- X extern void getlinecol();
- X
- X getlinecol(); /* get "co" and "li" entries from termcap */
- X }
- X#endif
- X
- X/*
- X * If everything fails, use the old values
- X */
- X if (Columns <= 0 || Rows <= 0)
- X {
- X Columns = old_Columns;
- X Rows = old_Rows;
- X return 1;
- X }
- X debug2("mch_get_winsize: %dx%d\n", (int)Columns, (int)Rows);
- X
- X check_winsize();
- X script_winsize();
- X
- X/* if size changed: screenalloc will allocate new screen buffers */
- X return (0);
- X}
- X
- X void
- Xmch_set_winsize()
- X{
- X /* should try to set the window size to Rows and Columns */
- X}
- X
- X int
- Xcall_shell(cmd, dummy)
- X char *cmd;
- X int dummy;
- X{
- X int x;
- X char newcmd[1024];
- X
- X flushbuf();
- X
- X settmode(0); /* set to cooked mode */
- X
- X if (cmd == NULL)
- X x = system(p_sh);
- X else
- X { /* we use "sh" to start the shell, slow but easy */
- X sprintf(newcmd, "%s -c \"%s\"", p_sh, cmd);
- X x = system(newcmd);
- X }
- X if (x == 127)
- X {
- X smsg("Cannot execute shell sh");
- X outchar('\n');
- X }
- X else if (x)
- X {
- X smsg("%d returned", x);
- X outchar('\n');
- X }
- X
- X settmode(1); /* set to raw mode */
- X return x;
- X}
- X
- X/*
- X * The input characters are buffered to be able to check for a CTRL-C.
- X * This should be done with signals, but I don't know how to do that in
- X * a portable way for a tty in RAW mode.
- X */
- X
- X#define INBUFLEN 50
- Xstatic char inbuf[INBUFLEN]; /* internal typeahead buffer */
- Xstatic int inbufcount = 0; /* number of chars in inbuf[] */
- X
- X static int
- XRead(buf, maxlen)
- X char *buf;
- X long maxlen;
- X{
- X if (inbufcount == 0) /* if the buffer is empty, fill it */
- X fill_inbuf();
- X if (maxlen > inbufcount)
- X maxlen = inbufcount;
- X memmove(buf, inbuf, maxlen);
- X inbufcount -= maxlen;
- X if (inbufcount)
- X memmove(inbuf, inbuf + maxlen, inbufcount);
- X return (int)maxlen;
- X}
- X
- X void
- Xbreakcheck()
- X{
- X/*
- X * check for CTRL-C typed by reading all available characters
- X */
- X if (RealWaitForChar(0)) /* if characters available */
- X fill_inbuf();
- X}
- X
- X static void
- Xfill_inbuf()
- X{
- X int len;
- X
- X if (inbufcount >= INBUFLEN) /* buffer full */
- X return;
- X len = read(0, inbuf + inbufcount, (long)(INBUFLEN - inbufcount));
- X if (len <= 0) /* cannot read input??? */
- X {
- X fprintf(stderr, "Vim: Error reading input, exiting...\n");
- X exit(1);
- X }
- X while (len-- > 0)
- X {
- X /*
- X * if a CTRL-C was typed, remove it from the buffer and set got_int
- X */
- X if (inbuf[inbufcount] == 3)
- X {
- X /* remove everything typed before the CTRL-C */
- X memmove(inbuf, inbuf + inbufcount, len + 1);
- X inbufcount = 0;
- X got_int = TRUE;
- X flush_buffers(); /* remove all typeahead */
- X }
- X ++inbufcount;
- X }
- X}
- X
- X/*
- X * Wait "ticks" until a character is available from the keyboard or from inbuf[]
- X * ticks = -1 will block forever
- X */
- X
- X static int
- XWaitForChar(ticks)
- X int ticks;
- X{
- X if (inbufcount) /* something in inbuf[] */
- X return 1;
- X return RealWaitForChar(ticks);
- X}
- X
- X/*
- X * Wait "ticks" until a character is available from the keyboard
- X * ticks = -1 will block forever
- X */
- X static int
- XRealWaitForChar(ticks)
- X int ticks;
- X{
- X#ifndef FD_ZERO
- X struct pollfd fds;
- X
- X fds.fd = 0;
- X fds.events = POLLIN;
- X return (poll(&fds, 1, ticks));
- X#else
- X struct timeval tv;
- X fd_set fdset;
- X
- X if (ticks >= 0)
- X {
- X tv.tv_sec = ticks / 1000;
- X tv.tv_usec = (ticks % 1000) * (1000000/1000);
- X }
- X
- X FD_ZERO(&fdset);
- X FD_SET(0, &fdset);
- X return (select(1, &fdset, NULL, NULL, (ticks >= 0) ? &tv : NULL));
- X#endif
- X}
- X
- X int
- Xremove(buf)
- X#ifdef linux
- X const
- X#endif
- X char *buf;
- X{
- X return unlink(buf);
- X}
- X
- X#ifdef WILD_CARDS
- X/*
- X * ExpandWildCard() - this code does wild-card pattern matching using the shell
- X *
- X * Mool: return 0 for success, 1 for error (you may loose some memory) and
- X * put an error message in *file.
- X *
- X * num_pat is number of input patterns
- X * pat is array of pointers to input patterns
- X * num_file is pointer to number of matched file names
- X * file is pointer to array of pointers to matched file names
- X * On Unix we do not check for files only yet
- X * list_notfound is ignored
- X */
- X
- Xextern char *mktemp __ARGS((char *));
- X#ifndef SEEK_SET
- X# define SEEK_SET 0
- X#endif
- X#ifndef SEEK_END
- X# define SEEK_END 2
- X#endif
- X
- X int
- XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
- X int num_pat;
- X char **pat;
- X int *num_file;
- X char ***file;
- X int files_only;
- X int list_notfound;
- X{
- X char tmpname[TMPNAMELEN];
- X char *command;
- X int i;
- X size_t len;
- X FILE *fd;
- X char *buffer;
- X char *p;
- X
- X *num_file = 0; /* default: no files found */
- X *file = (char **)"";
- X
- X/*
- X * get a name for the temp file
- X */
- X strcpy(tmpname, TMPNAME2);
- X if (*mktemp(tmpname) == NUL)
- X {
- X emsg(e_notmp);
- X return 1;
- X }
- X
- X/*
- X * let the shell expand the patterns and write the result into the temp file
- X */
- X len = TMPNAMELEN + 10;
- X for (i = 0; i < num_pat; ++i) /* count the length of the patterns */
- X len += strlen(pat[i]) + 3;
- X command = (char *)alloc(len);
- X if (command == NULL)
- X return 1;
- X strcpy(command, "echo > "); /* built the shell command */
- X strcat(command, tmpname);
- X for (i = 0; i < num_pat; ++i)
- X {
- X strcat(command, " \"");
- X strcat(command, pat[i]);
- X strcat(command, "\"");
- X }
- X i = call_shell(command, 0); /* execute it */
- X free(command);
- X if (i) /* call_shell failed */
- X {
- X remove(tmpname);
- X sleep(1); /* give the user a chance to read error messages */
- X updateScreen(CLEAR); /* probably messed up screen */
- X return 1;
- X }
- X
- X/*
- X * read the names from the file into memory
- X */
- X fd = fopen(tmpname, "r");
- X if (fd == NULL)
- X {
- X emsg(e_notopen);
- X return 1;
- X }
- X fseek(fd, 0L, SEEK_END);
- X len = ftell(fd); /* get size of temp file */
- X fseek(fd, 0L, SEEK_SET);
- X buffer = (char *)alloc(len + 1);
- X if (buffer == NULL)
- X {
- X remove(tmpname);
- X fclose(fd);
- X return 1;
- X }
- X i = fread(buffer, 1, len, fd);
- X fclose(fd);
- X remove(tmpname);
- X if (i != len)
- X {
- X emsg(e_notread);
- X free(buffer);
- X return 1;
- X }
- X buffer[len] = '\n'; /* make sure the buffers ends in NL */
- X
- X p = buffer;
- X for (i = 0; *p != '\n'; ++i) /* get number of entries */
- X {
- X while (*p != ' ' && *p != '\n') /* skip entry */
- X ++p;
- X skipspace(&p); /* skip to next entry */
- X }
- X *num_file = i;
- X *file = (char **)alloc(sizeof(char *) * i);
- X if (*file == NULL)
- X {
- X free(buffer);
- X *file = (char **)"";
- X return 1;
- X }
- X p = buffer;
- X for (i = 0; i < *num_file; ++i)
- X {
- X (*file)[i] = p;
- X while (*p != ' ' && *p != '\n')
- X ++p;
- X if (*p == '\n')
- X {
- X *p = NUL;
- X break;
- X }
- X *p++ = NUL;
- X skipspace(&p);
- X }
- X return 0;
- X}
- X
- X void
- XFreeWild(num, file)
- X int num;
- X char **file;
- X{
- X if (file == NULL || num <= 0)
- X return;
- X free(file[0]);
- X free(file);
- X}
- X
- X int
- Xhas_wildcard(p)
- X char *p;
- X{
- X for ( ; *p; ++p)
- X if (strchr("*?[{`~$", *p) != NULL)
- X return 1;
- X return 0;
- X}
- X#endif /* WILD_CARDS */
- X
- X#ifdef M_XENIX
- X/*
- X * Scaled-down version of rename, which is missing in Xenix.
- X * This version can only move regular files and will fail if the
- X * destination exists.
- X */
- X int
- Xrename(src, dst)
- X char *src, *dst;
- X{
- X struct stat st;
- X
- X if (stat(dest, &st) >= 0) /* fail if destination exists */
- X return -1;
- X if (link(src, dest) != 0) /* link file to new name */
- X return -1;
- X if (unlink(src) == 0) /* delete link to old name */
- X return 0;
- X return -1;
- X}
- X#endif /* M_XENIX */
- END_OF_FILE
- if test 15625 -ne `wc -c <'vim/src/unix.c'`; then
- echo shar: \"'vim/src/unix.c'\" unpacked with wrong size!
- fi
- # end of 'vim/src/unix.c'
- fi
- echo shar: End of archive 8 \(of 23\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 23 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- -------------8<----------------8<----------------8<---------------8<--------
- Bram Moolenaar | DISCLAIMER: This note does not
- Oce Nederland B.V., Research & Development | necessarily represent the position
- p.o. box 101, 5900 MA Venlo | of Oce-Nederland B.V. Therefore
- The Netherlands phone +31 77 594077 | no liability or responsibility for
- UUCP: mool@oce.nl fax +31 77 595450 | whatever will be accepted.
-
- exit 0 # Just in case...
-