home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume37 / vim / part08 < prev    next >
Text File  |  1993-04-23  |  54KB  |  2,317 lines

  1. Newsgroups: comp.sources.misc
  2. From: mool@oce.nl (Bram Moolenaar)
  3. Subject: v37i008:  vim - Vi IMitation editor v1.27, Part08/24
  4. Message-ID: <1993Apr23.173136.16790@sparky.imd.sterling.com>
  5. X-Md4-Signature: 828bada50568f29a1bbd1595b9b8f97b
  6. Date: Fri, 23 Apr 1993 17:31:36 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mool@oce.nl (Bram Moolenaar)
  10. Posting-number: Volume 37, Issue 8
  11. Archive-name: vim/part08
  12. Environment: UNIX, AMIGA, MS-DOS
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 8 (of 23)."
  21. # Contents:  vim/src/edit.c vim/src/param.c vim/src/unix.c
  22. # Wrapped by mool@oce-rd2 on Mon Apr 19 15:50:09 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'vim/src/edit.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'vim/src/edit.c'\"
  26. else
  27. echo shar: Extracting \"'vim/src/edit.c'\" \(16324 characters\)
  28. sed "s/^X//" >'vim/src/edit.c' <<'END_OF_FILE'
  29. X/* vi:ts=4:sw=4
  30. X *
  31. X * VIM - Vi IMitation
  32. X *
  33. X * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  34. X *                            Tim Thompson            twitch!tjt
  35. X *                            Tony Andrews            onecom!wldrdg!tony 
  36. X *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  37. X */
  38. X
  39. X/*
  40. X * edit.c: functions for insert mode
  41. X */
  42. X
  43. X#include "vim.h"
  44. X#include "globals.h"
  45. X#include "proto.h"
  46. X#include "param.h"
  47. X#include "ops.h"    /* for operator */
  48. X
  49. Xextern u_char *get_inserted();
  50. Xstatic void start_arrow __ARGS((void));
  51. Xstatic void stop_arrow __ARGS((void));
  52. Xstatic void stop_insert __ARGS((void));
  53. X
  54. Xint arrow_used;            /* Normally FALSE, set to TRUE after hitting
  55. X                             * cursor key in insert mode. Used by vgetorpeek()
  56. X                             * to decide when to call u_sync() */
  57. Xint restart_edit;        /* call edit when next command finished */
  58. Xstatic u_char    *last_insert = NULL;
  59. X                            /* the text of the previous insert */
  60. Xstatic int        last_insert_skip;
  61. X                            /* number of chars in front of the previous insert */
  62. Xstatic int        new_insert_skip;
  63. X                            /* number of chars in front of the current insert */
  64. X
  65. X    void
  66. Xedit(count)
  67. X    long count;
  68. X{
  69. X    u_char         c;
  70. X    u_char         cc;
  71. X    u_char        *ptr;
  72. X    linenr_t     lnum;
  73. X    int          temp = 0, mode;
  74. X    int             nextc = 0;
  75. X
  76. X#ifdef DIGRAPHS
  77. X    int             inserted = 0;        /* last 'normal' inserted char */
  78. X    int             backspaced = 0;    /* last backspace char */
  79. X#endif /* DIGRAPHS */
  80. X
  81. X    if (restart_edit)
  82. X    {
  83. X        arrow_used = TRUE;
  84. X        restart_edit = FALSE;
  85. X    }
  86. X    else
  87. X        arrow_used = FALSE;
  88. X
  89. X/*
  90. X * Get the current length of the redo buffer, those characters have to be
  91. X * skipped if we want to get to the inserted characters.
  92. X */
  93. X
  94. X    ptr = get_inserted();
  95. X    new_insert_skip = strlen((char *)ptr);
  96. X    free(ptr);
  97. X
  98. X    for (;;)
  99. X    {
  100. X        if (arrow_used)        /* don't repeat insert when arrow key used */
  101. X            count = 0;
  102. X
  103. X        set_want_col = TRUE;    /* set Curswant in case of K_DARROW or K_UARROW */
  104. X        cursupdate();        /* Figure out where the cursor is based on Curpos. */
  105. X        setcursor();
  106. X        if (nextc)            /* character remaining from CTRL-V */
  107. X        {
  108. X            c = nextc;
  109. X            nextc = 0;
  110. X        }
  111. X        else
  112. X            c = vgetc();
  113. X
  114. X#ifdef DIGRAPHS
  115. X        if (p_dg)
  116. X        {
  117. X            if (backspaced)
  118. X                c = getdigraph(backspaced, c);
  119. X            backspaced = 0;
  120. X            if (c == BS && inserted)
  121. X                backspaced = inserted;
  122. X            else
  123. X                inserted = c;
  124. X        }
  125. X#endif /* DIGRAPHS */
  126. X
  127. X        if (c == Ctrl('V'))
  128. X        {
  129. X                outchar('^');
  130. X                AppendToRedobuff("\026");    /* CTRL-V */
  131. X                cursupdate();
  132. X                setcursor();
  133. X
  134. X                c = get_literal(&nextc);
  135. X
  136. X            /* erase the '^' */
  137. X                if ((cc = gcharCurpos()) == NUL)
  138. X                    outchar(' ');
  139. X                else
  140. X                    outstrn(transchar(cc));
  141. X
  142. X                insertchar(c);
  143. X                continue;
  144. X        }
  145. X        switch (c)        /* handle character in insert mode */
  146. X        {
  147. X              case Ctrl('O'):        /* execute one command */
  148. X                  count = 0;
  149. X                restart_edit = TRUE;
  150. X                /*FALLTHROUGH*/
  151. X
  152. X              case ESC: /* an escape ends input mode */
  153. X        doESCkey:
  154. X                if (!arrow_used)
  155. X                {
  156. X                    AppendToRedobuff(ESC_STR);
  157. X
  158. X                    if (--count > 0)        /* repeat what was typed */
  159. X                    {
  160. X                            start_redo_ins();
  161. X                            continue;
  162. X                    }
  163. X                    stop_insert();
  164. X                }
  165. X                set_want_col = TRUE;
  166. X
  167. X                /*
  168. X                 * The cursor should end up on the last inserted character.
  169. X                 */
  170. X                if (Curpos.col != 0 && (!restart_edit || gcharCurpos() == NUL))
  171. X                    decCurpos();
  172. X                State = NORMAL;
  173. X                script_winsize_pp();    /* may need to put :winsize in script */
  174. X                    /* inchar() may have deleted the "INSERT" message */
  175. X                if (Recording)
  176. X                    showmode();
  177. X                else if (p_mo)
  178. X                    msg("");
  179. X                return;
  180. X
  181. X                  /*
  182. X                 * Insert the previously inserted text.
  183. X                 * Last_insert actually is a copy of the redo buffer, so we
  184. X                 * first have to remove the command.
  185. X                 * For ^@ the trailing ESC will end the insert.
  186. X                 */
  187. X              case K_ZERO:
  188. X              case Ctrl('A'):
  189. X                stuff_inserted(NUL, 1L, (c == Ctrl('A')));
  190. X                break;
  191. X
  192. X                  /*
  193. X                 * insert the contents of a register
  194. X                 */
  195. X              case Ctrl('B'):
  196. X                  if (!insertbuf(vgetc()))
  197. X                    beep();
  198. X                break;
  199. X
  200. X                /*
  201. X                 * If the cursor is on an indent, ^T/^D insert/delete one
  202. X                 * shiftwidth. Otherwise ^T/^D behave like a TAB/backspace.
  203. X                 * This isn't completely compatible with
  204. X                 * vi, but the difference isn't very noticeable and now you can
  205. X                 * mix ^D/backspace and ^T/TAB without thinking about which one
  206. X                 * must be used.
  207. X                 */
  208. X              case Ctrl('T'):        /* make indent one shiftwidth greater */
  209. X              case Ctrl('D'):         /* make indent one shiftwidth smaller */
  210. X                stop_arrow();
  211. X                AppendToRedobuff(mkstr(c));
  212. X
  213. X                    /* determine offset from first non-blank */
  214. X                temp = Curpos.col;
  215. X                beginline(TRUE);
  216. X                temp -= Curpos.col;
  217. X
  218. X                  shift_line(c == Ctrl('D'));
  219. X
  220. X                    /* try to put cursor on same character */
  221. X                temp += Curpos.col;
  222. X                if (temp <= 0)
  223. X                    Curpos.col = 0;
  224. X                else
  225. X                    Curpos.col = temp;
  226. X                did_ai = FALSE;
  227. X                did_si = FALSE;
  228. X                can_si = FALSE;
  229. X                  goto redraw;
  230. X
  231. X              case BS:
  232. X              case DEL:
  233. Xnextbs:
  234. X                mode = 0;
  235. Xdodel:
  236. X                /* can't backup past first character in buffer */
  237. X                /* can't backup past starting point unless "backspace" > 1 */
  238. X                /* can backup to a previous line if "backspace" == 0 */
  239. X                if ((Curpos.lnum == 1 && Curpos.col <= 0) ||
  240. X                        (p_bs < 2 && (arrow_used ||
  241. X                            (Curpos.lnum == Insstart.lnum &&
  242. X                            Curpos.col <= Insstart.col) ||
  243. X                            (Curpos.col <= 0 && p_bs == 0))))
  244. X                {
  245. X                    beep();
  246. X                    goto redraw;
  247. X                }
  248. X
  249. X                stop_arrow();
  250. X                if (Curpos.col <= 0)        /* delete newline! */
  251. X                {
  252. X                    if (Curpos.lnum == Insstart.lnum)
  253. X                    {
  254. X                        if (!u_save((linenr_t)(Curpos.lnum - 2), (linenr_t)(Curpos.lnum + 1)))
  255. X                            goto redraw;
  256. X                        --Insstart.lnum;
  257. X                        Insstart.col = 0;
  258. X                    }
  259. X                /* in replace mode with 'repdel' off we only move the cursor */
  260. X                    if (State != REPLACE || p_rd)
  261. X                    {
  262. X                        temp = gcharCurpos();        /* remember current char */
  263. X                        --Curpos.lnum;
  264. X                        dojoin(FALSE);
  265. X                        if (temp == NUL && gcharCurpos() != NUL)
  266. X                            ++Curpos.col;
  267. X                    }
  268. X                    else
  269. X                        decCurpos();
  270. X                    did_ai = FALSE;
  271. X                }
  272. X                else
  273. X                {
  274. X                    /* delete upto starting point, start of line or previous word */
  275. X                    do
  276. X                    {
  277. X                        decCurpos();
  278. X                                /* start of word? */
  279. X                        if (mode == 1 && !isspace(gcharCurpos()))
  280. X                        {
  281. X                            mode = 2;
  282. X                            temp = isidchar(gcharCurpos());
  283. X                        }
  284. X                                /* end of word? */
  285. X                        if (mode == 2 && isidchar(gcharCurpos()) != temp)
  286. X                        {
  287. X                            incCurpos();
  288. X                            break;
  289. X                        }
  290. X                        if (State != REPLACE || p_rd)
  291. X                            delchar(TRUE);
  292. X                        if (mode == 0)        /* just a single backspace */
  293. X                            break;
  294. X                    } while (Curpos.col > 0 && (Curpos.lnum != Insstart.lnum ||
  295. X                            Curpos.col != Insstart.col));
  296. X                }
  297. X                did_si = FALSE;
  298. X                can_si = FALSE;
  299. X                if (Curpos.col <= 1)
  300. X                    did_ai = FALSE;
  301. X                /*
  302. X                 * It's a little strange to put backspaces into the redo
  303. X                 * buffer, but it makes auto-indent a lot easier to deal
  304. X                 * with.
  305. X                 */
  306. X                AppendToRedobuff(mkstr(c));
  307. X                if (vpeekc() == BS)
  308. X                {
  309. X                        c = vgetc();
  310. X                        goto nextbs;    /* speedup multiple backspaces */
  311. X                }
  312. Xredraw:
  313. X                cursupdate();
  314. X                updateline();
  315. X                break;
  316. X
  317. X              case Ctrl('W'):
  318. X                  /* delete word before cursor */
  319. X                  mode = 1;
  320. X                  goto dodel;
  321. X
  322. X              case Ctrl('U'):
  323. X                mode = 3;
  324. X                  goto dodel;
  325. X
  326. X              case K_LARROW:
  327. X                  if (oneleft())
  328. X                    start_arrow();
  329. X                else
  330. X                    beep();
  331. X                break;
  332. X
  333. X              case K_SLARROW:
  334. X                  if (Curpos.lnum > 1 || Curpos.col > 0)
  335. X                {
  336. X                    bck_word(1L, 0);
  337. X                    start_arrow();
  338. X                }
  339. X                else
  340. X                    beep();
  341. X                break;
  342. X
  343. X              case K_RARROW:
  344. X                if (gcharCurpos() != NUL)
  345. X                {
  346. X                    set_want_col = TRUE;
  347. X                    start_arrow();
  348. X                    ++Curpos.col;
  349. X                }
  350. X                else
  351. X                    beep();
  352. X                break;
  353. X
  354. X              case K_SRARROW:
  355. X                  if (Curpos.lnum < line_count || gcharCurpos() != NUL)
  356. X                {
  357. X                    fwd_word(1L, 0);
  358. X                    start_arrow();
  359. X                }
  360. X                else
  361. X                    beep();
  362. X                break;
  363. X
  364. X              case K_UARROW:
  365. X                  if (oneup(1L))
  366. X                    start_arrow();
  367. X                else
  368. X                    beep();
  369. X                break;
  370. X
  371. X              case K_SUARROW:
  372. X                  if (onepage(BACKWARD, 1L))
  373. X                    start_arrow();
  374. X                else
  375. X                    beep();
  376. X                break;
  377. X
  378. X              case K_DARROW:
  379. X                  if (onedown(1L))
  380. X                    start_arrow();
  381. X                else
  382. X                    beep();
  383. X                break;
  384. X
  385. X              case K_SDARROW:
  386. X                  if (onepage(FORWARD, 1L))
  387. X                    start_arrow();
  388. X                else
  389. X                    beep();
  390. X                break;
  391. X
  392. X              case TAB:
  393. X                  if (!p_et)
  394. X                    goto normalchar;
  395. X                                        /* expand a tab into spaces */
  396. X                stop_arrow();
  397. X                did_ai = FALSE;
  398. X                did_si = FALSE;
  399. X                can_si = FALSE;
  400. X                insstr("                " + 16 - (p_ts - Curpos.col % p_ts));
  401. X                AppendToRedobuff("\t");
  402. X                goto redraw;
  403. X
  404. X              case CR:
  405. X              case NL:
  406. X                stop_arrow();
  407. X                if (State == REPLACE)           /* DMT added, 12/89 */
  408. X                    delchar(FALSE);
  409. X                AppendToRedobuff(NL_STR);
  410. X                if (!Opencmd(FORWARD, TRUE))
  411. X                    goto doESCkey;        /* out of memory */
  412. X                break;
  413. X
  414. X#ifdef DIGRAPHS
  415. X              case Ctrl('K'):
  416. X                outchar('?');
  417. X                AppendToRedobuff("\026");    /* CTRL-V */
  418. X                setcursor();
  419. X                  c = vgetc();
  420. X                outstrn(transchar(c));
  421. X                setcursor();
  422. X                c = getdigraph(c, vgetc());
  423. X                goto normalchar;
  424. X#endif /* DIGRAPHS */
  425. X
  426. X              case Ctrl('R'):
  427. X                /*
  428. X                 * addition by mool: copy from previous line
  429. X                 */
  430. X                lnum = Curpos.lnum - 1;
  431. X                goto copychar;
  432. X
  433. X              case Ctrl('E'):
  434. X                lnum = Curpos.lnum + 1;
  435. Xcopychar:
  436. X                if (lnum < 1 || lnum > line_count)
  437. X                {
  438. X                    beep();
  439. X                    break;
  440. X                }
  441. X
  442. X                /* try to advance to the cursor column */
  443. X                temp = 0;
  444. X                ptr = (u_char *)nr2ptr(lnum);
  445. X                while (temp < Cursvcol && *ptr)
  446. X                        temp += chartabsize(*ptr++, temp);
  447. X
  448. X                if (temp > Cursvcol)
  449. X                        --ptr;
  450. X                if ((c = *ptr) == NUL)
  451. X                {
  452. X                    beep();
  453. X                    break;
  454. X                }
  455. X
  456. X                /*FALLTHROUGH*/
  457. X              default:
  458. Xnormalchar:
  459. X                if (Curpos.col > 0 && ((can_si && c == '}') || (did_si && c == '{')))
  460. X                    shift_line(TRUE);
  461. X                insertchar(c);
  462. X                break;
  463. X            }
  464. X    }
  465. X}
  466. X
  467. X/*
  468. X * Next character is interpreted literally.
  469. X * A one, two or three digit decimal number is interpreted as its byte value.
  470. X * If one or two digits are entered, *nextc is set to the next character.
  471. X */
  472. X    int
  473. Xget_literal(nextc)
  474. X    int *nextc;
  475. X{
  476. X    u_char         cc;
  477. X    u_char         nc;
  478. X    int             oldstate;
  479. X    int             i;
  480. X
  481. X    oldstate = State;
  482. X    State = NOMAPPING;        /* next characters not mapped */
  483. X
  484. X    cc = 0;
  485. X    for (i = 0; i < 3; ++i)
  486. X    {
  487. X        nc = vgetc();
  488. X        if (!isdigit(nc))
  489. X            break;
  490. X        cc = cc * 10 + nc - '0';
  491. X        nc = 0;
  492. X    }
  493. X    if (i == 0)        /* no number entered */
  494. X    {
  495. X        cc = nc;
  496. X        nc = 0;
  497. X    }
  498. X    else if (cc == 0)        /* NUL is stored as NL */
  499. X        cc = '\n';
  500. X
  501. X    State = oldstate;
  502. X    *nextc = nc;
  503. X    return cc;
  504. X}
  505. X
  506. X/*
  507. X * Special characters in this context are those that need processing other
  508. X * than the simple insertion that can be performed here. This includes ESC
  509. X * which terminates the insert, and CR/NL which need special processing to
  510. X * open up a new line. This routine tries to optimize insertions performed by
  511. X * the "redo", "undo" or "put" commands, so it needs to know when it should
  512. X * stop and defer processing to the "normal" mechanism.
  513. X */
  514. X#define ISSPECIAL(c)    ((c) < ' ' || (c) >= DEL)
  515. X
  516. X    void
  517. Xinsertchar(c)
  518. X    unsigned    c;
  519. X{
  520. X    int        must_redraw = FALSE;
  521. X
  522. X    stop_arrow();
  523. X    /*
  524. X     * If the cursor is past 'textwidth' and we are inserting a non-space,
  525. X     * try to break the line in two or more pieces. If c == NUL then we have
  526. X     * been called to do formatting only.
  527. X     */
  528. X    if (c == NUL || !isspace(c))
  529. X    {
  530. X        while (Cursvcol >= p_tw)
  531. X        {
  532. X            int        startcol;        /* Cursor column at entry */
  533. X            int        wantcol;        /* column at textwidth border */
  534. X            int        foundcol;        /* column for start of word */
  535. X            int        mincol;            /* minimum column for break */
  536. X
  537. X            if ((startcol = Curpos.col) == 0)
  538. X                break;
  539. X            coladvance((int)p_tw);    /* find column of textwidth border */
  540. X            wantcol = Curpos.col;
  541. X            beginline((int)p_ai);            /* find start of text */
  542. X            mincol = Curpos.col;
  543. X
  544. X            Curpos.col = startcol - 1;
  545. X            foundcol = 0;
  546. X            while (Curpos.col > mincol)    /* find position to break at */
  547. X            {
  548. X                if (isspace(gcharCurpos()))
  549. X                {
  550. X                    foundcol = Curpos.col + 1;
  551. X                    while (Curpos.col > 1 && isspace(gcharCurpos()))
  552. X                        --Curpos.col;
  553. X                    if (Curpos.col < wantcol)
  554. X                        break;
  555. X                }
  556. X                --Curpos.col;
  557. X            }
  558. X
  559. X            if (foundcol == 0)    /* no spaces, cannot break line */
  560. X            {
  561. X                Curpos.col = startcol;
  562. X                break;
  563. X            }
  564. X            Curpos.col = foundcol;
  565. X            startcol -= Curpos.col;
  566. X            Opencmd(FORWARD, FALSE);
  567. X            Curpos.col += startcol;
  568. X            curs_columns();            /* update Cursvcol */
  569. X            must_redraw = TRUE;
  570. X        }
  571. X        if (c == NUL)        /* formatting only */
  572. X            return;
  573. X        if (must_redraw)
  574. X            updateScreen(CURSUPD);
  575. X    }
  576. X
  577. X    did_ai = FALSE;
  578. X    did_si = FALSE;
  579. X    can_si = FALSE;
  580. X
  581. X    /*
  582. X     * If there's any pending input, grab up to MAX_COLUMNS at once.
  583. X     * This speeds up normal text input considerably.
  584. X     */
  585. X    if (vpeekc() != NUL && State != REPLACE)
  586. X    {
  587. X        char            p[MAX_COLUMNS + 1];
  588. X        int             i;
  589. X
  590. X        p[0] = c;
  591. X        i = 1;
  592. X        while ((c = vpeekc()) != NUL && !ISSPECIAL(c) && i < MAX_COLUMNS &&
  593. X                    (Cursvcol += charsize(p[i - 1])) < p_tw)
  594. X            p[i++] = vgetc();
  595. X        p[i] = '\0';
  596. X        insstr(p);
  597. X        AppendToRedobuff(p);
  598. X    }
  599. X    else
  600. X    {
  601. X        inschar(c);
  602. X        AppendToRedobuff(mkstr(c));
  603. X    }
  604. X
  605. X    updateline();
  606. X}
  607. X
  608. X
  609. X/*
  610. X * start_arrow() is called when an arrow key is used in insert mode.
  611. X * It resembles hitting the <ESC> key.
  612. X */
  613. X    static void
  614. Xstart_arrow()
  615. X{
  616. X    if (!arrow_used)        /* something has been inserted */
  617. X    {
  618. X        AppendToRedobuff(ESC_STR);
  619. X        arrow_used = TRUE;        /* this means we stopped the current insert */
  620. X        stop_insert();
  621. X    }
  622. X}
  623. X
  624. X/*
  625. X * stop_arrow() is called before a change is made in insert mode.
  626. X * If an arrow key has been used, start a new insertion.
  627. X */
  628. X    static void
  629. Xstop_arrow()
  630. X{
  631. X    if (arrow_used)
  632. X    {
  633. X        u_saveCurpos();            /* errors are ignored! */
  634. X        Insstart = Curpos;        /* new insertion starts here */
  635. X        ResetBuffers();
  636. X        AppendToRedobuff("1i");    /* pretend we start an insertion */
  637. X        arrow_used = FALSE;
  638. X    }
  639. X}
  640. X
  641. X/*
  642. X * do a few things to stop inserting
  643. X */
  644. X    static void
  645. Xstop_insert()
  646. X{
  647. X    stop_redo_ins();
  648. X
  649. X    /*
  650. X     * save the inserted text for later redo with ^@
  651. X     */
  652. X    free(last_insert);
  653. X    last_insert = get_inserted();
  654. X    last_insert_skip = new_insert_skip;
  655. X
  656. X    /*
  657. X     * If we just did an auto-indent, truncate the line, and put
  658. X     * the cursor back.
  659. X     */
  660. X    if (did_ai && !arrow_used)
  661. X    {
  662. X        *nr2ptr(Curpos.lnum) = NUL;
  663. X        canincrease(0);
  664. X        Curpos.col = 0;
  665. X    }
  666. X    did_ai = FALSE;
  667. X    did_si = FALSE;
  668. X    can_si = FALSE;
  669. X}
  670. X
  671. X/*
  672. X * oneright oneleft onedown oneup
  673. X *
  674. X * Move one char {right,left,down,up}.    Return TRUE when sucessful, FALSE when
  675. X * we hit a boundary (of a line, or the file).
  676. X */
  677. X
  678. X    int
  679. Xoneright()
  680. X{
  681. X    char *ptr;
  682. X
  683. X    ptr = pos2ptr(&Curpos);
  684. X    set_want_col = TRUE;
  685. X
  686. X    if (*ptr++ == NUL || *ptr == NUL)
  687. X        return FALSE;
  688. X    ++Curpos.col;
  689. X    return TRUE;
  690. X}
  691. X
  692. X    int
  693. Xoneleft()
  694. X{
  695. X    set_want_col = TRUE;
  696. X
  697. X    if (Curpos.col == 0)
  698. X        return FALSE;
  699. X    --Curpos.col;
  700. X    return TRUE;
  701. X}
  702. X
  703. X    void
  704. Xbeginline(flag)
  705. X    int            flag;
  706. X{
  707. X    Curpos.col = 0;
  708. X    if (flag)
  709. X    {
  710. X        register char *ptr;
  711. X
  712. X        for (ptr = nr2ptr(Curpos.lnum); isspace(*ptr); ++ptr)
  713. X            ++Curpos.col;
  714. X    }
  715. X    set_want_col = TRUE;
  716. X}
  717. X
  718. X    int
  719. Xoneup(n)
  720. X    long n;
  721. X{
  722. X    if (n != 0 && Curpos.lnum == 1)
  723. X        return FALSE;
  724. X    if (n >= Curpos.lnum)
  725. X        Curpos.lnum = 1;
  726. X    else
  727. X        Curpos.lnum -= n;
  728. X
  729. X    if (operator == NOP)
  730. X        cursupdate();                /* make sure Topline is valid */
  731. X
  732. X    /* try to advance to the column we want to be at */
  733. X    coladvance(Curswant);
  734. X    return TRUE;
  735. X}
  736. X
  737. X    int
  738. Xonedown(n)
  739. X    long n;
  740. X{
  741. X    if (n != 0 && Curpos.lnum == line_count)
  742. X        return FALSE;
  743. X    Curpos.lnum += n;
  744. X    if (Curpos.lnum > line_count)
  745. X        Curpos.lnum = line_count;
  746. X
  747. X    if (operator == NOP)
  748. X        cursupdate();                /* make sure Topline is valid */
  749. X
  750. X    /* try to advance to the column we want to be at */
  751. X    coladvance(Curswant);
  752. X    return TRUE;
  753. X}
  754. X
  755. X    int
  756. Xonepage(dir, count)
  757. X    int        dir;
  758. X    long    count;
  759. X{
  760. X    linenr_t        lp;
  761. X    long            n;
  762. X
  763. X    if (line_count == 1)    /* nothing to do */
  764. X        return FALSE;
  765. X    for ( ; count > 0; --count)
  766. X    {
  767. X        if (dir == FORWARD ? (Topline >= line_count - 1) : (Topline == 1))
  768. X        {
  769. X            beep();
  770. X            return FALSE;
  771. X        }
  772. X        lp = Topline;
  773. X        n = 0;
  774. X        if (dir == BACKWARD)
  775. X        {
  776. X            if (lp < line_count)
  777. X                ++lp;
  778. X            Curpos.lnum = lp;
  779. X        }
  780. X        while (n < Rows - 1 && lp >= 1 && lp <= line_count)
  781. X        {
  782. X            n += plines(lp);
  783. X            lp += dir;
  784. X        }
  785. X        if (dir == FORWARD)
  786. X        {
  787. X            if (--lp > 1)
  788. X                --lp;
  789. X            Topline = Curpos.lnum = lp;
  790. X        }
  791. X        else
  792. X            Topline = lp + 1;
  793. X    }
  794. X    beginline(TRUE);
  795. X    updateScreen(VALID);
  796. X    return TRUE;
  797. X}
  798. X
  799. X    void
  800. Xstuff_inserted(c, count, no_esc)
  801. X    int        c;
  802. X    long    count;
  803. X    int        no_esc;
  804. X{
  805. X    u_char        *esc_ptr = NULL;
  806. X    u_char        *ptr;
  807. X
  808. X    if (last_insert == NULL)
  809. X    {
  810. X        beep();
  811. X        return;
  812. X    }
  813. X    if (c)
  814. X        stuffReadbuff(mkstr(c));
  815. X    if (no_esc && (esc_ptr = (u_char *)strrchr((char *)last_insert, 27)) != NULL)
  816. X        *esc_ptr = NUL;        /* remove the ESC */
  817. X
  818. X            /* skip the command */
  819. X    ptr = last_insert + last_insert_skip;
  820. X
  821. X    do
  822. X        stuffReadbuff((char *)ptr);
  823. X    while (--count > 0);
  824. X
  825. X    if (no_esc && esc_ptr)
  826. X        *esc_ptr = 27;        /* put the ESC back */
  827. X}
  828. END_OF_FILE
  829. if test 16324 -ne `wc -c <'vim/src/edit.c'`; then
  830.     echo shar: \"'vim/src/edit.c'\" unpacked with wrong size!
  831. fi
  832. # end of 'vim/src/edit.c'
  833. fi
  834. if test -f 'vim/src/param.c' -a "${1}" != "-c" ; then 
  835.   echo shar: Will not clobber existing file \"'vim/src/param.c'\"
  836. else
  837. echo shar: Extracting \"'vim/src/param.c'\" \(16498 characters\)
  838. sed "s/^X//" >'vim/src/param.c' <<'END_OF_FILE'
  839. X/* vi:ts=4:sw=4
  840. X *
  841. X * VIM - Vi IMitation
  842. X *
  843. X * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  844. X *                            Tim Thompson            twitch!tjt
  845. X *                            Tony Andrews            onecom!wldrdg!tony 
  846. X *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  847. X */
  848. X
  849. X/*
  850. X * Code to handle user-settable parameters. This is all pretty much table-
  851. X * driven. To add a new parameter, put it in the params array, and add a
  852. X * variable for it in param.h. If it's a numeric parameter, add any necessary
  853. X * bounds checks to doset().
  854. X */
  855. X
  856. X#include "vim.h"
  857. X#include "globals.h"
  858. X#include "proto.h"
  859. X#include "param.h"
  860. X
  861. Xstruct param
  862. X{
  863. X    char        *fullname;        /* full parameter name */
  864. X    char        *shortname;     /* permissible abbreviation */
  865. X    int         flags;            /* see below */
  866. X    char        *var;            /* pointer to variable */
  867. X};
  868. X
  869. X/*
  870. X * Flags
  871. X */
  872. X#define P_BOOL            0x01    /* the parameter is boolean */
  873. X#define P_NUM            0x02    /* the parameter is numeric */
  874. X#define P_STRING        0x04    /* the parameter is a string */
  875. X#define P_CHANGED        0x08    /* the parameter has been changed */
  876. X
  877. X/*
  878. X * The param structure is initialized here.
  879. X * The order of the parameters should be alfabetic
  880. X */
  881. Xstruct param params[] =
  882. X{
  883. X        {"autoindent",    "ai",    P_BOOL,        (char *)&p_ai},
  884. X/*        {"autoprint",    "ap",    P_BOOL,        (char *)&p_ap}, */
  885. X        {"autowrite",    "aw",    P_BOOL,        (char *)&p_aw},
  886. X        {"backspace",    "bs",    P_NUM,        (char *)&p_bs},
  887. X        {"backup",        "bk",    P_BOOL,        (char *)&p_bk},
  888. X#ifdef UNIX
  889. X         {"backupdir",    "bdir",    P_STRING,    (char *)&p_bdir},
  890. X#endif
  891. X/*        {"beautify",    "bf",    P_BOOL,        (char *)&p_bf}, */
  892. X        {"columns",        "co",    P_NUM,        (char *)&Columns},
  893. X        {"compatible",    "cp",    P_BOOL,        (char *)&p_cp},
  894. X#ifdef DIGRAPHS
  895. X        {"digraph",        "dg",    P_BOOL,        (char *)&p_dg},
  896. X#endif /* DIGRAPHS */
  897. X         {"directory",    "dir",    P_STRING,    (char *)&p_dir},
  898. X        {"equalprg",    "ep",      P_STRING,    (char *)&p_ep},
  899. X        {"errorbells",    "eb",    P_BOOL,        (char *)&p_eb},
  900. X        {"errorfile",    "ef",      P_STRING,    (char *)&p_ef},
  901. X        {"expandtab",    "et",    P_BOOL,        (char *)&p_et},
  902. X        {"graphic",        "gr",    P_BOOL,        (char *)&p_gr},
  903. X/*        {"hardtabs",    "ht",    P_NUM,        (char *)&p_ht}, */
  904. X        {"helpfile",    "hf",      P_STRING,    (char *)&p_hf},
  905. X        {"history",     "hi",     P_NUM,        (char *)&p_hi},
  906. X        {"ignorecase",    "ic",    P_BOOL,        (char *)&p_ic},
  907. X        {"insertmode",    "im",    P_BOOL,        (char *)&p_im},
  908. X        {"joinspaces",     "js",    P_BOOL,        (char *)&p_js},
  909. X        {"keywordprg",    "kp",      P_STRING,    (char *)&p_kp},
  910. X        {"lines",        NULL,     P_NUM,        (char *)&Rows},
  911. X/*        {"lisp",        NULL,    P_BOOL        (char *)&p_lisp}, */
  912. X        {"list",        NULL,    P_BOOL,        (char *)&p_list},
  913. X        {"magic",        NULL,    P_BOOL,        (char *)&p_magic},
  914. X        {"modelines",    "ml",    P_NUM,        (char *)&p_ml},
  915. X        {"number",        "nu",    P_BOOL,        (char *)&p_nu},
  916. X/*        {"open",        NULL,    P_BOOL,        (char *)&p_open}, */
  917. X/*        {"optimize",    "opt",    P_BOOL,        (char *)&p_opt}, */
  918. X        {"paragraphs",    "para",    P_STRING,    (char *)&p_para},
  919. X/*        {"prompt",        NULL,    P_BOOL,        (char *)&p_prompt}, */
  920. X        {"readonly",    "ro",    P_BOOL,        (char *)&p_ro},
  921. X/*        {"redraw",        NULL,    P_BOOL,        (char *)&p_redraw}, */
  922. X        {"remap",        NULL,    P_BOOL,        (char *)&p_remap},
  923. X        {"repdel",        "rd",    P_BOOL,        (char *)&p_rd},
  924. X        {"report",        NULL,    P_NUM,        (char *)&p_report},
  925. X        {"ruler",        "ru",    P_BOOL,        (char *)&p_ru},
  926. X        {"scroll",        NULL,     P_NUM,        (char *)&p_scroll},
  927. X        {"scrolljump",    "sj",     P_NUM,        (char *)&p_sj},
  928. X        {"sections",    NULL,    P_STRING,    (char *)&p_sections},
  929. X        {"shell",        "sh",    P_STRING,    (char *)&p_sh},
  930. X        {"shelltype",    "st",    P_NUM,        (char *)&p_st},
  931. X        {"shiftround",    "sr",    P_BOOL,        (char *)&p_sr},
  932. X        {"shiftwidth",    "sw",    P_NUM,        (char *)&p_sw},
  933. X#ifndef MSDOS
  934. X        {"shortname",    "sn",    P_BOOL,        (char *)&p_sn},
  935. X#endif
  936. X        {"showcmd",        "sc",    P_BOOL,        (char *)&p_sc},
  937. X        {"showmatch",    "sm",    P_BOOL,        (char *)&p_sm},
  938. X        {"showmode",    "mo",    P_BOOL,        (char *)&p_mo},
  939. X/*        {"slowopen",    "slow",    P_BOOL,        (char *)&p_slow}, */
  940. X        {"smartindent", "si",    P_BOOL,        (char *)&p_si},
  941. X        {"suffixes",    "su",    P_STRING,    (char *)&p_su},
  942. X        {"tabstop",     "ts",    P_NUM,        (char *)&p_ts},
  943. X        {"taglength",    "tl",    P_NUM,        (char *)&p_tl},
  944. X        {"tags",        NULL,    P_STRING,    (char *)&p_tags},
  945. X        {"term",        NULL,    P_STRING,    (char *)&term_strings.t_name},
  946. X        {"terse",        NULL,    P_BOOL,        (char *)&p_terse},
  947. X#ifdef MSDOS
  948. X        {"textmode",    "tx",    P_BOOL,        (char *)&p_tx},
  949. X#endif
  950. X        {"textwidth",    "tw",    P_NUM,        (char *)&p_tw},
  951. X        {"tildeop",     "to",    P_BOOL,        (char *)&p_to},
  952. X        {"timeout",     NULL,    P_BOOL,        (char *)&p_timeout},
  953. X        {"ttimeout",     NULL,    P_BOOL,        (char *)&p_ttimeout},
  954. X        {"undolevels",    "ul",    P_NUM,        (char *)&p_ul},
  955. X        {"updatecount",    "uc",    P_NUM,        (char *)&p_uc},
  956. X        {"updatetime",    "ut",    P_NUM,        (char *)&p_ut},
  957. X        {"visualbell",    "vb",    P_BOOL,        (char *)&p_vb},
  958. X        {"warn",        NULL,    P_BOOL,        (char *)&p_warn},
  959. X/*        {"window",        NULL,     P_NUM,        (char *)&p_window}, */
  960. X/*        {"w300",        NULL,     P_NUM,        (char *)&p_w300}, */
  961. X/*        {"w1200",        NULL,     P_NUM,        (char *)&p_w1200}, */
  962. X/*        {"w9600",        NULL,     P_NUM,        (char *)&p_w9600}, */
  963. X        {"wrapscan",    "ws",    P_BOOL,        (char *)&p_ws},
  964. X        {"wrapmargin",    "wm",    P_NUM,        (char *)&p_wm},
  965. X        {"writeany",    "wa",    P_BOOL,        (char *)&p_wa},
  966. X        {"writebackup",    "wb",    P_BOOL,        (char *)&p_wb},
  967. X        {"yankendofline", "ye",    P_BOOL,        (char *)&p_ye},
  968. X
  969. X/* terminal output codes */
  970. X        {"t_el",        NULL,    P_STRING,    (char *)&term_strings.t_el},
  971. X        {"t_il",        NULL,    P_STRING,    (char *)&term_strings.t_il},
  972. X        {"t_cil",        NULL,    P_STRING,    (char *)&term_strings.t_cil},
  973. X        {"t_dl",        NULL,    P_STRING,    (char *)&term_strings.t_dl},
  974. X        {"t_cdl",        NULL,    P_STRING,    (char *)&term_strings.t_cdl},
  975. X        {"t_ed",        NULL,    P_STRING,    (char *)&term_strings.t_ed},
  976. X        {"t_ci",        NULL,    P_STRING,    (char *)&term_strings.t_ci},
  977. X        {"t_cv",        NULL,    P_STRING,    (char *)&term_strings.t_cv},
  978. X        {"t_tp",        NULL,    P_STRING,    (char *)&term_strings.t_tp},
  979. X        {"t_ti",        NULL,    P_STRING,    (char *)&term_strings.t_ti},
  980. X        {"t_cm",        NULL,    P_STRING,    (char *)&term_strings.t_cm},
  981. X        {"t_sr",        NULL,    P_STRING,    (char *)&term_strings.t_sr},
  982. X        {"t_cri",        NULL,    P_STRING,    (char *)&term_strings.t_cri},
  983. X        {"t_vb",        NULL,    P_STRING,    (char *)&term_strings.t_vb},
  984. X        {"t_ks",        NULL,    P_STRING,    (char *)&term_strings.t_ks},
  985. X        {"t_ke",        NULL,    P_STRING,    (char *)&term_strings.t_ke},
  986. X        {"t_ts",        NULL,    P_STRING,    (char *)&term_strings.t_ts},
  987. X        {"t_te",        NULL,    P_STRING,    (char *)&term_strings.t_te},
  988. X
  989. X/* terminal key codes */
  990. X        {"t_ku",        NULL,    P_STRING,    (char *)&term_strings.t_ku},
  991. X        {"t_kd",        NULL,    P_STRING,    (char *)&term_strings.t_kd},
  992. X        {"t_kr",        NULL,    P_STRING,    (char *)&term_strings.t_kr},
  993. X        {"t_kl",        NULL,    P_STRING,    (char *)&term_strings.t_kl},
  994. X        {"t_sku",        NULL,    P_STRING,    (char *)&term_strings.t_sku},
  995. X        {"t_skd",        NULL,    P_STRING,    (char *)&term_strings.t_skd},
  996. X        {"t_skr",        NULL,    P_STRING,    (char *)&term_strings.t_skr},
  997. X        {"t_skl",        NULL,    P_STRING,    (char *)&term_strings.t_skl},
  998. X        {"t_f1",        NULL,    P_STRING,    (char *)&term_strings.t_f1},
  999. X        {"t_f2",        NULL,    P_STRING,    (char *)&term_strings.t_f2},
  1000. X        {"t_f3",        NULL,    P_STRING,    (char *)&term_strings.t_f3},
  1001. X        {"t_f4",        NULL,    P_STRING,    (char *)&term_strings.t_f4},
  1002. X        {"t_f5",        NULL,    P_STRING,    (char *)&term_strings.t_f5},
  1003. X        {"t_f6",        NULL,    P_STRING,    (char *)&term_strings.t_f6},
  1004. X        {"t_f7",        NULL,    P_STRING,    (char *)&term_strings.t_f7},
  1005. X        {"t_f8",        NULL,    P_STRING,    (char *)&term_strings.t_f8},
  1006. X        {"t_f9",        NULL,    P_STRING,    (char *)&term_strings.t_f9},
  1007. X        {"t_f10",        NULL,    P_STRING,    (char *)&term_strings.t_f10},
  1008. X        {"t_sf1",        NULL,    P_STRING,    (char *)&term_strings.t_sf1},
  1009. X        {"t_sf2",        NULL,    P_STRING,    (char *)&term_strings.t_sf2},
  1010. X        {"t_sf3",        NULL,    P_STRING,    (char *)&term_strings.t_sf3},
  1011. X        {"t_sf4",        NULL,    P_STRING,    (char *)&term_strings.t_sf4},
  1012. X        {"t_sf5",        NULL,    P_STRING,    (char *)&term_strings.t_sf5},
  1013. X        {"t_sf6",        NULL,    P_STRING,    (char *)&term_strings.t_sf6},
  1014. X        {"t_sf7",        NULL,    P_STRING,    (char *)&term_strings.t_sf7},
  1015. X        {"t_sf8",        NULL,    P_STRING,    (char *)&term_strings.t_sf8},
  1016. X        {"t_sf9",        NULL,    P_STRING,    (char *)&term_strings.t_sf9},
  1017. X        {"t_sf10",        NULL,    P_STRING,    (char *)&term_strings.t_sf10},
  1018. X        {"t_help",        NULL,    P_STRING,    (char *)&term_strings.t_help},
  1019. X        {"t_undo",        NULL,    P_STRING,    (char *)&term_strings.t_undo},
  1020. X        {NULL, NULL, 0, NULL}            /* end marker */
  1021. X};
  1022. X
  1023. Xstatic void    showparams __ARGS((int));
  1024. Xstatic void showonep __ARGS((struct param *));
  1025. Xstatic int  istermparam __ARGS((struct param *));
  1026. X
  1027. X/*
  1028. X * Initialize the shell parameter and scroll size.
  1029. X */
  1030. X    void
  1031. Xset_init()
  1032. X{
  1033. X        char *p;
  1034. X
  1035. X        if ((p = (char *)vimgetenv("SHELL")) != NULL)
  1036. X            p_sh = strsave(p);
  1037. X        p_scroll = (Rows >> 1);
  1038. X}
  1039. X
  1040. X    void
  1041. Xdoset(arg)
  1042. X    char        *arg;    /* parameter string */
  1043. X{
  1044. X    register int i;
  1045. X    char        *s;
  1046. X    char        *errmsg;
  1047. X    char        *startarg;
  1048. X    int            prefix;    /* 0: nothing, 1: "no", 2: "inv" in front of name */
  1049. X    int         nextchar;
  1050. X    int         len = 0;
  1051. X    int         flags;
  1052. X    int            olduc = p_uc;    /* remember old update count */
  1053. X
  1054. X    if (*arg == NUL)
  1055. X    {
  1056. X        showparams(0);
  1057. X        return;
  1058. X    }
  1059. X
  1060. X    while (*arg)        /* loop to process all parameters */
  1061. X    {
  1062. X        errmsg = NULL;
  1063. X        startarg = arg;        /* remember for error message */
  1064. X        if (strncmp(arg, "all", (size_t)3) == 0)
  1065. X                showparams(1);
  1066. X        else if (strncmp(arg, "termcap", (size_t)7) == 0)
  1067. X                showparams(2);
  1068. X        else
  1069. X        {
  1070. X            prefix = 1;
  1071. X            if (strncmp(arg, "no", (size_t)2) == 0)
  1072. X            {
  1073. X                prefix = 0;
  1074. X                arg += 2;
  1075. X            }
  1076. X            else if (strncmp(arg, "inv", (size_t)3) == 0)
  1077. X            {
  1078. X                prefix = 2;
  1079. X                arg += 3;
  1080. X            }
  1081. X            for (i = 0; (s = params[i].fullname) != NULL; i++)
  1082. X            {
  1083. X                if (strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match full name */
  1084. X                    break;
  1085. X            }
  1086. X            if (s == NULL)
  1087. X            {
  1088. X                for (i = 0; params[i].fullname != NULL; i++)
  1089. X                {
  1090. X                        s = params[i].shortname;
  1091. X                        if (s != NULL && strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match short name */
  1092. X                            break;
  1093. X                        s = NULL;
  1094. X                }
  1095. X            }
  1096. X
  1097. X            if (s == NULL)        /* found a mismatch: skip the rest */
  1098. X            {
  1099. X                errmsg = "Unknown option:   ";    /* must be 18 chars */
  1100. X                goto skip;
  1101. X            }
  1102. X
  1103. X            flags = params[i].flags;
  1104. X            nextchar = arg[len];
  1105. X            /*
  1106. X             * allow '=' and ':' as MSDOS command.com allows only one
  1107. X             * '=' character per "set" command line. grrr. (jw)
  1108. X             */
  1109. X            if (nextchar == '?' || 
  1110. X                (prefix == 1 && nextchar != '=' &&
  1111. X                 nextchar != ':' && !(flags & P_BOOL)))
  1112. X            {                                        /* print value */
  1113. X                gotocmdline(TRUE, NUL);
  1114. X                showonep(¶ms[i]);
  1115. X            }
  1116. X            else if (nextchar != NUL && strchr("=: \t", nextchar) == NULL)
  1117. X            {
  1118. X                errmsg = e_setarg;
  1119. X                goto skip;
  1120. X            }
  1121. X            else if (flags & P_BOOL)                    /* boolean */
  1122. X            {
  1123. X                    if (nextchar == '=' || nextchar == ':')
  1124. X                    {
  1125. X                        errmsg = e_setarg;
  1126. X                        goto skip;
  1127. X                    }
  1128. X                    if (prefix == 2)
  1129. X                        *(int *)(params[i].var) ^= 1;    /* invert it */
  1130. X                    else
  1131. X                        *(int *)(params[i].var) = prefix;
  1132. X                    if ((int *)params[i].var == &p_cp && p_cp)    /* handle cp here */
  1133. X                    {
  1134. X                        p_bs = 0;        /* normal backspace */
  1135. X                        p_bk = 0;        /* no backup file */
  1136. X#ifdef DIGRAPHS
  1137. X                        p_dg = 0;        /* no digraphs */
  1138. X#endif /* DIGRAPHS */
  1139. X                        p_et = 0;        /* no expansion of tabs */
  1140. X                        p_hi = 0;        /* no history */
  1141. X                        p_im = 0;        /* do not start in insert mode */
  1142. X                        p_js = 1;        /* insert 2 spaces after period */
  1143. X                        p_ml = 0;        /* no modelines */
  1144. X                        p_rd = 1;        /* del replaces char */
  1145. X                        p_ru = 0;        /* no ruler */
  1146. X                        p_sj = 1;        /* no scrolljump */
  1147. X                        p_sr = 0;        /* do not round indent to shiftwidth */
  1148. X                        p_sc = 0;        /* no showcommand */
  1149. X                        p_mo = 0;        /* no showmode */
  1150. X                        p_si = 0;        /* no smartindent */
  1151. X                        p_tw = 9999;    /* maximum textwidth */
  1152. X                        p_to = 0;        /* no tilde operator */
  1153. X                        p_ttimeout = 0;    /* no terminal timeout */
  1154. X                        p_ul = 0;        /* no multilevel undo */
  1155. X                        p_uc = 0;        /* no autoscript file */
  1156. X                        p_wb = 0;        /* no backup file */
  1157. X                        p_ye = 0;        /* no yank to end of line */
  1158. X                    }
  1159. X            }
  1160. X            else                                /* numeric or string */
  1161. X            {
  1162. X                if ((nextchar != '=' && nextchar != ':') || prefix != 1)
  1163. X                {
  1164. X                    errmsg = e_setarg;
  1165. X                    goto skip;
  1166. X                }
  1167. X                if (flags & P_NUM)                /* numeric */
  1168. X                {
  1169. X                    len = atoi(arg + len + 1);
  1170. X                    if ((long *)params[i].var == &p_wm)    /* wrapmargin is translated into textlength */
  1171. X                    {
  1172. X                        if (len >= Columns)
  1173. X                            len = Columns - 1;
  1174. X                        p_tw = Columns - len;
  1175. X                    }
  1176. X                    *(long *)(params[i].var) = len;
  1177. X                }
  1178. X                else                            /* string */
  1179. X                {
  1180. X                    arg += len + 1;
  1181. X                    s = alloc((unsigned)(strlen(arg) + 1)); /* get a bit too much */
  1182. X                    if (s == NULL)
  1183. X                        break;
  1184. X                    if (flags & P_CHANGED)
  1185. X                        free(*(char **)(params[i].var));
  1186. X                    *(char **)(params[i].var) = s;
  1187. X                                /* copy the string */
  1188. X                    while (*arg && *arg != ' ' && *arg != '\t')
  1189. X                    {
  1190. X                        if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */
  1191. X                                ++arg;
  1192. X                        *s++ = *arg++;
  1193. X                    }
  1194. X                    *s = NUL;
  1195. X                    /*
  1196. X                     * options that need some action
  1197. X                     * to perform when changed (jw)
  1198. X                     */
  1199. X                    if (params[i].var == (char *)&term_strings.t_name)
  1200. X                        set_term(term_strings.t_name);
  1201. X                    else if (istermparam(¶ms[i]))
  1202. X                        ttest(FALSE);
  1203. X                }
  1204. X            }
  1205. X            params[i].flags |= P_CHANGED;
  1206. X        }
  1207. X
  1208. Xskip:
  1209. X        if (errmsg)
  1210. X        {
  1211. X            strcpy(IObuff, errmsg);
  1212. X            s = IObuff + 18;
  1213. X            while (*startarg && !isspace(*startarg))
  1214. X                *s++ = *startarg++;
  1215. X            *s = NUL;
  1216. X            emsg(IObuff);
  1217. X            arg = startarg;        /* skip to next argument */
  1218. X        }
  1219. X
  1220. X        skiptospace(&arg);                /* skip to next white space */
  1221. X        skipspace(&arg);                /* skip spaces */
  1222. X    }
  1223. X
  1224. X    /*
  1225. X     * Check the bounds for numeric parameters here
  1226. X     */
  1227. X    if (Rows < 2)
  1228. X    {
  1229. X        Rows = 2;
  1230. X        emsg("Need at least 2 lines");
  1231. X    }
  1232. X    if (p_ts <= 0 || p_ts > 16)
  1233. X    {
  1234. X        emsg(e_tabsize);
  1235. X        p_ts = 8;
  1236. X    }
  1237. X    if (p_scroll <= 0 || p_scroll > Rows)
  1238. X    {
  1239. X        emsg(e_scroll);
  1240. X        p_scroll = Rows >> 1;
  1241. X    }
  1242. X    if (p_report < 0)
  1243. X    {
  1244. X        emsg(e_positive);
  1245. X        p_report = 1;
  1246. X    }
  1247. X    if (p_sj < 0 || p_sj >= Rows)
  1248. X    {
  1249. X        emsg(e_scroll);
  1250. X        p_sj = 1;
  1251. X    }
  1252. X    if (p_ul < 0)
  1253. X    {
  1254. X        emsg(e_positive);
  1255. X        p_ul = 100;
  1256. X    }
  1257. X    if (p_uc < 0)
  1258. X    {
  1259. X        emsg(e_positive);
  1260. X        p_uc = 100;
  1261. X    }
  1262. X    if (p_uc == 0 && olduc != 0)        /* p_uc changed from on to off */
  1263. X        stopscript();
  1264. X    if (p_uc > 0 && olduc == 0)        /* p_uc changed from off to on */
  1265. X        startscript();
  1266. X#ifdef MSDOS
  1267. X    textfile(p_tx);
  1268. X#endif
  1269. X    if (p_ut < 0)
  1270. X    {
  1271. X        emsg(e_positive);
  1272. X        p_ut = 2000;
  1273. X    }
  1274. X
  1275. X    /*
  1276. X     * Update the screen in case we changed something like "tabstop" or
  1277. X     * "lines" or "list" that will change its appearance.
  1278. X     */
  1279. X    updateScreen(NOT_VALID);
  1280. X}
  1281. X
  1282. X/*
  1283. X * if 'all' == 0: show changed parameters
  1284. X * if 'all' == 1: show all normal parameters
  1285. X * if 'all' == 2: show all terminal parameters
  1286. X */
  1287. X    static void
  1288. Xshowparams(all)
  1289. X    int            all;
  1290. X{
  1291. X    struct param   *p;
  1292. X    int                col = 0;
  1293. X    int                inc;
  1294. X    int                isterm;
  1295. X
  1296. X    gotocmdline(TRUE, NUL);
  1297. X    outstrn("Parameters:\n");
  1298. X
  1299. X#ifdef AMIGA
  1300. X    settmode(0);                /* set cooked mode so output can be halted */
  1301. X#endif
  1302. X    for (p = ¶ms[0]; p->fullname != NULL; p++)
  1303. X    {
  1304. X        isterm = istermparam(p);
  1305. X        if ((all == 2 && isterm) ||
  1306. X            (all == 1 && !isterm) ||
  1307. X            (all == 0 && (p->flags & P_CHANGED)))
  1308. X        {
  1309. X            if ((p->flags & P_STRING) && *(char **)(p->var) != NULL)
  1310. X                inc = strlen(p->fullname) + strsize(*(char **)(p->var)) + 1;
  1311. X            else
  1312. X                inc = 1;
  1313. X            if (col + inc >= Columns)
  1314. X            {
  1315. X                outchar('\n');
  1316. X                col = 0;
  1317. X            }
  1318. X
  1319. X            showonep(p);
  1320. X            col += inc;
  1321. X            col += 19 - col % 19;
  1322. X            if (col < Columns - 19)
  1323. X                windgoto((int)Rows - 1, col); /* make columns */
  1324. X            else
  1325. X            {
  1326. X                col = 0;
  1327. X                outchar('\n');
  1328. X            }
  1329. X            flushbuf();
  1330. X        }
  1331. X    }
  1332. X
  1333. X    if (col)
  1334. X        outchar('\n');
  1335. X#ifdef AMIGA
  1336. X    settmode(1);
  1337. X#endif
  1338. X    wait_return(TRUE);
  1339. X}
  1340. X
  1341. X    static void
  1342. Xshowonep(p)
  1343. X        struct param *p;
  1344. X{
  1345. X    char            buf[64];
  1346. X
  1347. X    if ((p->flags & P_BOOL) && !*(int *)(p->var))
  1348. X        outstrn("no");
  1349. X    outstrn(p->fullname);
  1350. X    if (!(p->flags & P_BOOL))
  1351. X    {
  1352. X        outchar('=');
  1353. X        if (p->flags & P_NUM)
  1354. X        {
  1355. X            sprintf(buf, "%ld", *(long *)(p->var));
  1356. X            outstrn(buf);
  1357. X        }
  1358. X        else if (*(char **)(p->var) != NULL)
  1359. X            outtrans(*(char **)(p->var), -1);
  1360. X    }
  1361. X}
  1362. X
  1363. X/*
  1364. X * Write modified parameters as set command to a file.
  1365. X * Return 1 on error.
  1366. X */
  1367. X    int
  1368. Xmakeset(fd)
  1369. X    FILE *fd;
  1370. X{
  1371. X    struct param    *p;
  1372. X    char            *s;
  1373. X    int                e;
  1374. X
  1375. X    for (p = ¶ms[0]; p->fullname != NULL; p++)
  1376. X        if (p->flags & P_CHANGED)
  1377. X        {
  1378. X            if (p->flags & P_BOOL)
  1379. X                e = fprintf(fd, "set %s%s\n", *(int *)(p->var) ? "" : "no", p->fullname);
  1380. X            else if (p->flags & P_NUM)
  1381. X                e = fprintf(fd, "set %s=%ld\n", p->fullname, *(long *)(p->var));
  1382. X            else
  1383. X            {
  1384. X                fprintf(fd, "set %s=", p->fullname);
  1385. X                s = *(char **)(p->var);
  1386. X                if (s != NULL)
  1387. X                    for ( ; *s; ++s)
  1388. X                    {
  1389. X                        if (*s < ' ' || *s > '~')
  1390. X                            putc(Ctrl('V'), fd);
  1391. X                        putc(*s, fd);
  1392. X                    }
  1393. X                e = putc('\n', fd);
  1394. X            }
  1395. X            if (e < 0)
  1396. X                return 1;
  1397. X        }
  1398. X    return 0;
  1399. X}
  1400. X
  1401. X/*
  1402. X * Clear all the terminal parameters.
  1403. X * If the parameter has been changed, free the allocated memory.
  1404. X * Reset the "changed" flag, so the new value will not be freed.
  1405. X */
  1406. X    void
  1407. Xclear_termparam()
  1408. X{
  1409. X    struct param   *p;
  1410. X
  1411. X    for (p = ¶ms[0]; p->fullname != NULL; p++)
  1412. X        if (istermparam(p))
  1413. X        {
  1414. X            if (p->flags & P_CHANGED)
  1415. X                free(*(char **)(p->var));
  1416. X            *(char **)(p->var) = NULL;
  1417. X            p->flags &= ~P_CHANGED;
  1418. X        }
  1419. X}
  1420. X
  1421. X    static int
  1422. Xistermparam(p)
  1423. X    struct param *p;
  1424. X{
  1425. X    return (p->fullname[0] == 't' && p->fullname[1] == '_');
  1426. X}
  1427. END_OF_FILE
  1428. if test 16498 -ne `wc -c <'vim/src/param.c'`; then
  1429.     echo shar: \"'vim/src/param.c'\" unpacked with wrong size!
  1430. fi
  1431. # end of 'vim/src/param.c'
  1432. fi
  1433. if test -f 'vim/src/unix.c' -a "${1}" != "-c" ; then 
  1434.   echo shar: Will not clobber existing file \"'vim/src/unix.c'\"
  1435. else
  1436. echo shar: Extracting \"'vim/src/unix.c'\" \(15625 characters\)
  1437. sed "s/^X//" >'vim/src/unix.c' <<'END_OF_FILE'
  1438. X/* vi:ts=4:sw=4
  1439. X *
  1440. X *
  1441. X * VIM - Vi IMitation
  1442. X *
  1443. X * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  1444. X *                            Tim Thompson            twitch!tjt
  1445. X *                            Tony Andrews            onecom!wldrdg!tony 
  1446. X *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  1447. X */
  1448. X/*
  1449. X * unix.c -- BSD and SYSV code
  1450. X *
  1451. X * A lot of this file was written by Juergen Weigert.
  1452. X */
  1453. X
  1454. X#include "vim.h"
  1455. X#include "globals.h"
  1456. X#include "param.h"
  1457. X#include "proto.h"
  1458. X
  1459. X#include <fcntl.h>
  1460. X#if !defined(pyr) && !defined(NOT_BOTH_TIME)
  1461. X# include <time.h>            /* on some systems time.h should not be
  1462. X                               included together with sys/time.h */
  1463. X#endif
  1464. X#include <sys/ioctl.h>
  1465. X#ifndef M_XENIX
  1466. X# include <sys/types.h>
  1467. X#endif
  1468. X#include <signal.h>
  1469. X
  1470. X#ifdef SYSV
  1471. X# ifdef M_XENIX
  1472. X#  include <sys/select.h>
  1473. X#  define bzero(a, b)    memset((a), 0, (b))
  1474. X# else
  1475. X#  include <poll.h>
  1476. X# endif
  1477. X# include <termio.h>
  1478. X#else    /* SYSV */
  1479. X# include <sys/time.h>
  1480. X# ifdef hpux
  1481. X#  include <termio.h>
  1482. X#  define SIGWINCH SIGWINDOW
  1483. X# else
  1484. X#  include <sgtty.h>
  1485. X# endif    /* hpux */
  1486. X#endif    /* SYSV */
  1487. X
  1488. X#if (defined(pyr) || defined(NO_FD_ZERO)) && defined(SYSV) && defined(FD_ZERO)
  1489. X# undef FD_ZERO
  1490. X#endif
  1491. X
  1492. X#ifdef ESIX
  1493. X# ifdef SIGWINCH
  1494. X#  undef SIGWINCH
  1495. X# endif
  1496. X# ifdef TIOCGWINSZ
  1497. X#  undef TIOCGWINSZ
  1498. X# endif
  1499. X#endif
  1500. X
  1501. Xstatic int    Read __ARGS((char *, long));
  1502. Xstatic int    WaitForChar __ARGS((int));
  1503. Xstatic int    RealWaitForChar __ARGS((int));
  1504. Xstatic void fill_inbuf __ARGS((void));
  1505. X#if defined(SIGWINCH) && !defined(linux)
  1506. Xstatic void sig_winch __ARGS((int, int, struct sigcontext *));
  1507. X#endif
  1508. X
  1509. Xstatic int do_resize = FALSE;
  1510. X
  1511. X/*
  1512. X * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
  1513. X */
  1514. X#undef TRUE
  1515. X#define TRUE 1
  1516. X#undef FALSE
  1517. X#define FALSE 0
  1518. X
  1519. X/*
  1520. X * the number of calls to Write is reduced by using the buffer "outbuf"
  1521. X */
  1522. X#define BSIZE    2048
  1523. Xstatic u_char    outbuf[BSIZE];
  1524. Xstatic int        bpos = 0;
  1525. X
  1526. X/*
  1527. X * flushbuf(): flush the output buffer
  1528. X */
  1529. X    void
  1530. Xflushbuf()
  1531. X{
  1532. X    if (bpos != 0)
  1533. X        write(1, (char *)outbuf, (long)bpos);
  1534. X    bpos = 0;
  1535. X}
  1536. X
  1537. X/*
  1538. X * outchar(c): put a character into the output buffer. Flush it if it becomes full.
  1539. X */
  1540. X    void
  1541. Xoutchar(c)
  1542. X    unsigned c;
  1543. X{
  1544. X    if (c == '\n')        /* turn LF into CR-LF (CRMOD does not seem to do this) */
  1545. X        outchar('\r');
  1546. X    outbuf[bpos] = c;
  1547. X    ++bpos;
  1548. X    if (bpos >= BSIZE)
  1549. X        flushbuf();
  1550. X}
  1551. X
  1552. X/*
  1553. X * GetChars(): low level input funcion.
  1554. X * Get a characters from the keyboard.
  1555. X * If type == T_PEEK do not wait for characters.
  1556. X * If type == T_WAIT wait a short time for characters.
  1557. X * If type == T_BLOCK wait for characters.
  1558. X */
  1559. X    int
  1560. XGetChars(buf, maxlen, type)
  1561. X    char    *buf;
  1562. X    int        maxlen;
  1563. X    int        type;
  1564. X{
  1565. X    int        len;
  1566. X    int        time = 1000;    /* one second */
  1567. X
  1568. X    switch (type)
  1569. X    {
  1570. X    case T_PEEK:
  1571. X        time = 20;
  1572. X    case T_WAIT:
  1573. X        if (WaitForChar(time) == 0)        /* no character available */
  1574. X            return 0;
  1575. X        break;
  1576. X
  1577. X    case T_BLOCK:
  1578. X    /*
  1579. X     * If there is no character available within 2 seconds (default)
  1580. X     * write the autoscript file to disk
  1581. X     */
  1582. X        if (WaitForChar((int)p_ut) == 0)
  1583. X            updatescript(0);
  1584. X    }
  1585. X
  1586. X    for (;;)    /* repeat until we got a character */
  1587. X    {
  1588. X        /* 
  1589. X         * we want to be interrupted by the winch signal
  1590. X         */
  1591. X        WaitForChar(-1);
  1592. X        if (do_resize)
  1593. X        {
  1594. X            debug("do_resize!\n");
  1595. X            set_winsize(0, 0, FALSE);
  1596. X            do_resize = FALSE;
  1597. X            continue;
  1598. X        }
  1599. X        len = Read(buf, (long)maxlen);
  1600. X        if (len > 0)
  1601. X            return len;
  1602. X    }
  1603. X}
  1604. X
  1605. X    void
  1606. Xvim_delay()
  1607. X{
  1608. X#if defined(SYSV) && !defined(M_XENIX)
  1609. X    poll(0, 0, 500);
  1610. X#else
  1611. X    struct timeval tv;
  1612. X
  1613. X    tv.tv_sec = 25 / 50;
  1614. X    tv.tv_usec = (25 % 50) * (1000000/50);
  1615. X    select(0, 0, 0, 0, &tv);
  1616. X#endif
  1617. X}
  1618. X
  1619. X    static void
  1620. Xsig_winch(sig, code, scp)
  1621. X    int        sig;
  1622. X    int        code;
  1623. X    struct sigcontext *scp;
  1624. X{
  1625. X#if defined(SIGWINCH) && (defined(SYSV) || defined(linux) || defined(hpux))
  1626. X    signal(SIGWINCH, sig_winch);
  1627. X#endif
  1628. X    do_resize = TRUE;
  1629. X}
  1630. X
  1631. X/*
  1632. X * If the machine has job control, use it to suspend the program,
  1633. X * otherwise fake it by starting a new shell.
  1634. X */
  1635. X    void
  1636. Xmch_suspend()
  1637. X{
  1638. X#ifdef SIGTSTP
  1639. X    settmode(0);
  1640. X    stoptermcap();
  1641. X    kill(0, SIGTSTP);        /* send ourselves a STOP signal */
  1642. X    settmode(1);
  1643. X    starttermcap();
  1644. X#else
  1645. X    outstr("new shell started\n");
  1646. X    stoptermcap();
  1647. X    call_shell(NULL, 0);
  1648. X    starttermcap();
  1649. X#endif
  1650. X}
  1651. X
  1652. X    void
  1653. Xmch_windinit()
  1654. X{
  1655. X    Columns = 80;
  1656. X    Rows = 24;
  1657. X
  1658. X    flushbuf();
  1659. X
  1660. X    mch_get_winsize();
  1661. X#if defined(SIGWINCH)
  1662. X    signal(SIGWINCH, sig_winch);
  1663. X#endif
  1664. X}
  1665. X
  1666. X/*
  1667. X * Check_win checks whether we have an interactive window.
  1668. X * If not, a new window is opened with the newcli command.
  1669. X * If we would open a window ourselves, the :sh and :! commands would not
  1670. X * work properly (Why? probably because we are then running in a background CLI).
  1671. X * This also is the best way to assure proper working in a next Workbench release.
  1672. X *
  1673. X * For the -e option (quickfix mode) we open our own window and disable :sh.
  1674. X * Otherwise we would never know when editing is finished.
  1675. X */
  1676. X#define BUF2SIZE 320        /* lenght of buffer for argument with complete path */
  1677. X
  1678. X    void
  1679. Xcheck_win(argc, argv)
  1680. X    int argc;
  1681. X    char **argv;
  1682. X{
  1683. X    if (!isatty(0) || !isatty(1))
  1684. X    {
  1685. X        fprintf(stderr, "VIM: no controlling terminal\n");
  1686. X        exit(2);
  1687. X    }
  1688. X}
  1689. X
  1690. X/*
  1691. X * fname_case(): Set the case of the filename, if it already exists.
  1692. X *                 This will cause the filename to remain exactly the same.
  1693. X */
  1694. X    void
  1695. Xfname_case(name)
  1696. X    char *name;
  1697. X{
  1698. X}
  1699. X
  1700. X    void
  1701. Xsettitle(str)
  1702. X    char *str;
  1703. X{
  1704. X}
  1705. X
  1706. X    void
  1707. Xresettitle()
  1708. X{
  1709. X}
  1710. X
  1711. X/*
  1712. X * get name of current directory into buffer 'buf' of length 'len' bytes
  1713. X */
  1714. X    int 
  1715. Xdirname(buf, len)
  1716. X    char *buf;
  1717. X    int len;
  1718. X{
  1719. X#if defined(SYSV) || defined(hpux)
  1720. X    extern int        errno;
  1721. X    extern char        *sys_errlist[];
  1722. X
  1723. X    if (getcwd(buf,len) == NULL)
  1724. X    {
  1725. X        strcpy(buf, sys_errlist[errno]);
  1726. X        return 1;
  1727. X    }
  1728. X    return 0;
  1729. X#else
  1730. X    return (int)getwd(buf);
  1731. X#endif
  1732. X}
  1733. X
  1734. X/*
  1735. X * get absolute filename into buffer 'buf' of length 'len' bytes
  1736. X */
  1737. X    int 
  1738. XFullName(fname, buf, len)
  1739. X    char *fname, *buf;
  1740. X    int len;
  1741. X{
  1742. X    *buf = 0;
  1743. X#if defined(linux) || defined(UNIX_WITHOUT_AMD)
  1744. X    {
  1745. X        int l;
  1746. X
  1747. X        if (*fname != '/')
  1748. X        {
  1749. X#if defined(SYSV) || defined(hpux)
  1750. X            (void)getcwd(buf,len);
  1751. X#else
  1752. X            (void)getwd(buf);
  1753. X#endif
  1754. X            l = strlen(buf);
  1755. X            if (l && buf[l-1] != '/')
  1756. X                strcat(buf, "/");
  1757. X        }
  1758. X    }
  1759. X#endif /* UNIX_WITHOUT_AMD */
  1760. X    strcat(buf, fname);
  1761. X    return 0;
  1762. X}
  1763. X
  1764. X/*
  1765. X * get file permissions for 'name'
  1766. X */
  1767. X    long 
  1768. Xgetperm(name)
  1769. X    char *name;
  1770. X{
  1771. X    struct stat statb;
  1772. X
  1773. X    if (stat(name, &statb))
  1774. X        return -1;
  1775. X    return statb.st_mode;
  1776. X}
  1777. X
  1778. X/*
  1779. X * set file permission for 'name' to 'perm'
  1780. X */
  1781. X    int
  1782. Xsetperm(name, perm)
  1783. X    char *name;
  1784. X    int perm;
  1785. X{
  1786. X    return chmod(name, perm);
  1787. X}
  1788. X
  1789. X/*
  1790. X * check if "name" is a directory
  1791. X */
  1792. X    int 
  1793. Xisdir(name)
  1794. X    char *name;
  1795. X{
  1796. X    struct stat statb;
  1797. X
  1798. X    if (stat(name, &statb))
  1799. X        return -1;
  1800. X    return (statb.st_mode & S_IFMT) != S_IFREG;
  1801. X}
  1802. X
  1803. X    void
  1804. Xmch_windexit(r)
  1805. X    int r;
  1806. X{
  1807. X    settmode(0);
  1808. X    stoptermcap();
  1809. X    flushbuf();
  1810. X    stopscript();                    /* remove autoscript file */
  1811. X    exit(r);
  1812. X}
  1813. X
  1814. X    void
  1815. Xmch_settmode(raw)
  1816. X    int                raw;
  1817. X{
  1818. X#if defined(ECHOE) && defined(ICANON)
  1819. X    /* for "new" tty systems */
  1820. X    static struct termio told;
  1821. X           struct termio tnew;
  1822. X
  1823. X    if (raw)
  1824. X    {
  1825. X        ioctl(0, TCGETA, &told);
  1826. X        tnew = told;
  1827. X        tnew.c_iflag &= ~ICRNL;            /* enables typing ^V^M */
  1828. X        tnew.c_iflag &= ~IXON;            /* enables typing ^Q */
  1829. X        tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE);
  1830. X        tnew.c_cc[VMIN] = 1;            /* return after 1 char */
  1831. X        tnew.c_cc[VTIME] = 0;            /* don't wait */
  1832. X        ioctl(0, TCSETA, &tnew);
  1833. X    }
  1834. X    else
  1835. X        ioctl(0, TCSETA, &told);
  1836. X#else
  1837. X# ifndef TIOCSETN
  1838. X#  define TIOCSETN TIOCSETP        /* for hpux 9.0 */
  1839. X# endif
  1840. X    /* for "old" tty systems */
  1841. X    static struct sgttyb ttybold;
  1842. X           struct sgttyb ttybnew;
  1843. X
  1844. X    if (raw)
  1845. X    {
  1846. X        ioctl(0, TIOCGETP, &ttybold);
  1847. X        ttybnew = ttybold;
  1848. X        ttybnew.sg_flags &= ~(CRMOD | ECHO);
  1849. X        ttybnew.sg_flags |= RAW;
  1850. X        ioctl(0, TIOCSETN, &ttybnew);
  1851. X    }
  1852. X    else
  1853. X        ioctl(0, TIOCSETN, &ttybold);
  1854. X#endif
  1855. X}
  1856. X
  1857. X    int
  1858. Xmch_get_winsize()
  1859. X{
  1860. X    int                old_Rows = Rows;
  1861. X    int                old_Columns = Columns;
  1862. X    char            *p;
  1863. X
  1864. X    Columns = 0;
  1865. X    Rows = 0;
  1866. X
  1867. X/*
  1868. X * when called without a signal, get winsize from environment
  1869. X */
  1870. X    if (!do_resize)
  1871. X    {
  1872. X        if ((p = (char *)getenv("LINES")))
  1873. X            Rows = atoi(p);
  1874. X        if ((p = (char *)getenv("COLUMNS")))
  1875. X            Columns = atoi(p);
  1876. X        if (Columns <= 0 || Rows <= 0)
  1877. X            do_resize = TRUE;
  1878. X    }
  1879. X
  1880. X/*
  1881. X * when got a signal, or no size in environment, try using an ioctl
  1882. X */
  1883. X    if (do_resize)
  1884. X    {
  1885. X# ifdef TIOCGSIZE
  1886. X        struct ttysize    ts;
  1887. X
  1888. X        if (ioctl(0, TIOCGSIZE, &ts) == 0)
  1889. X        {
  1890. X            if (Columns == 0)
  1891. X                Columns = ts.ts_cols;
  1892. X            if (Rows == 0)
  1893. X                Rows = ts.ts_lines;
  1894. X        }
  1895. X# else /* TIOCGSIZE */
  1896. X#  ifdef TIOCGWINSZ
  1897. X        struct winsize    ws;
  1898. X
  1899. X        if (ioctl(0, TIOCGWINSZ, &ws) == 0)
  1900. X        {
  1901. X            if (Columns == 0)
  1902. X                Columns = ws.ws_col;
  1903. X            if (Rows == 0)
  1904. X                Rows = ws.ws_row;
  1905. X        }
  1906. X#  endif /* TIOCGWINSZ */
  1907. X# endif /* TIOCGSIZE */
  1908. X        do_resize = FALSE;
  1909. X    }
  1910. X
  1911. X#ifdef TERMCAP
  1912. X/*
  1913. X * if previous work fails, try reading the termcap
  1914. X */
  1915. X    if (Columns == 0 || Rows == 0)
  1916. X    {
  1917. X        extern void getlinecol();
  1918. X
  1919. X        getlinecol();    /* get "co" and "li" entries from termcap */
  1920. X    }
  1921. X#endif
  1922. X
  1923. X/*
  1924. X * If everything fails, use the old values
  1925. X */
  1926. X    if (Columns <= 0 || Rows <= 0)
  1927. X    {
  1928. X        Columns = old_Columns;
  1929. X        Rows = old_Rows;
  1930. X        return 1;
  1931. X    }
  1932. X    debug2("mch_get_winsize: %dx%d\n", (int)Columns, (int)Rows);
  1933. X
  1934. X    check_winsize();
  1935. X    script_winsize();
  1936. X
  1937. X/* if size changed: screenalloc will allocate new screen buffers */
  1938. X    return (0);
  1939. X}
  1940. X
  1941. X    void
  1942. Xmch_set_winsize()
  1943. X{
  1944. X    /* should try to set the window size to Rows and Columns */
  1945. X}
  1946. X
  1947. X    int 
  1948. Xcall_shell(cmd, dummy)
  1949. X    char    *cmd;
  1950. X    int        dummy;
  1951. X{
  1952. X    int        x;
  1953. X    char    newcmd[1024];
  1954. X
  1955. X    flushbuf();
  1956. X
  1957. X    settmode(0);                 /* set to cooked mode */
  1958. X
  1959. X    if (cmd == NULL)
  1960. X        x = system(p_sh);
  1961. X    else
  1962. X    {            /* we use "sh" to start the shell, slow but easy */
  1963. X        sprintf(newcmd, "%s -c \"%s\"", p_sh, cmd);
  1964. X        x = system(newcmd);
  1965. X    }
  1966. X    if (x == 127)
  1967. X    {
  1968. X        smsg("Cannot execute shell sh");
  1969. X        outchar('\n');
  1970. X    }
  1971. X    else if (x)
  1972. X    {
  1973. X        smsg("%d returned", x);
  1974. X        outchar('\n');
  1975. X    }
  1976. X
  1977. X    settmode(1);                         /* set to raw mode */
  1978. X    return x;
  1979. X}
  1980. X
  1981. X/*
  1982. X * The input characters are buffered to be able to check for a CTRL-C.
  1983. X * This should be done with signals, but I don't know how to do that in
  1984. X * a portable way for a tty in RAW mode.
  1985. X */
  1986. X
  1987. X#define INBUFLEN 50
  1988. Xstatic char        inbuf[INBUFLEN];    /* internal typeahead buffer */
  1989. Xstatic int        inbufcount = 0;        /* number of chars in inbuf[] */
  1990. X
  1991. X    static int
  1992. XRead(buf, maxlen)
  1993. X    char    *buf;
  1994. X    long    maxlen;
  1995. X{
  1996. X    if (inbufcount == 0)        /* if the buffer is empty, fill it */
  1997. X        fill_inbuf();
  1998. X    if (maxlen > inbufcount)
  1999. X        maxlen = inbufcount;
  2000. X    memmove(buf, inbuf, maxlen);
  2001. X    inbufcount -= maxlen;
  2002. X    if (inbufcount)
  2003. X            memmove(inbuf, inbuf + maxlen, inbufcount);
  2004. X    return (int)maxlen;
  2005. X}
  2006. X
  2007. X    void
  2008. Xbreakcheck()
  2009. X{
  2010. X/*
  2011. X * check for CTRL-C typed by reading all available characters
  2012. X */
  2013. X    if (RealWaitForChar(0))        /* if characters available */
  2014. X        fill_inbuf();
  2015. X}
  2016. X
  2017. X    static void
  2018. Xfill_inbuf()
  2019. X{
  2020. X    int        len;
  2021. X
  2022. X    if (inbufcount >= INBUFLEN)        /* buffer full */
  2023. X        return;
  2024. X    len = read(0, inbuf + inbufcount, (long)(INBUFLEN - inbufcount));
  2025. X    if (len <= 0)    /* cannot read input??? */
  2026. X    {
  2027. X        fprintf(stderr, "Vim: Error reading input, exiting...\n");
  2028. X        exit(1);
  2029. X    }
  2030. X    while (len-- > 0)
  2031. X    {
  2032. X        /*
  2033. X         * if a CTRL-C was typed, remove it from the buffer and set got_int
  2034. X         */
  2035. X        if (inbuf[inbufcount] == 3)
  2036. X        {
  2037. X            /* remove everything typed before the CTRL-C */
  2038. X            memmove(inbuf, inbuf + inbufcount, len + 1);
  2039. X            inbufcount = 0;
  2040. X            got_int = TRUE;
  2041. X            flush_buffers();        /* remove all typeahead */
  2042. X        }
  2043. X        ++inbufcount;
  2044. X    }
  2045. X}
  2046. X
  2047. X/* 
  2048. X * Wait "ticks" until a character is available from the keyboard or from inbuf[]
  2049. X * ticks = -1 will block forever
  2050. X */
  2051. X
  2052. X    static int
  2053. XWaitForChar(ticks)
  2054. X    int ticks;
  2055. X{
  2056. X    if (inbufcount)        /* something in inbuf[] */
  2057. X        return 1;
  2058. X    return RealWaitForChar(ticks);
  2059. X}
  2060. X
  2061. X/* 
  2062. X * Wait "ticks" until a character is available from the keyboard
  2063. X * ticks = -1 will block forever
  2064. X */
  2065. X    static int
  2066. XRealWaitForChar(ticks)
  2067. X    int ticks;
  2068. X{
  2069. X#ifndef FD_ZERO
  2070. X    struct pollfd fds;
  2071. X
  2072. X    fds.fd = 0;
  2073. X    fds.events = POLLIN;
  2074. X    return (poll(&fds, 1, ticks));
  2075. X#else
  2076. X    struct timeval tv;
  2077. X    fd_set fdset;
  2078. X
  2079. X    if (ticks >= 0)
  2080. X    {
  2081. X           tv.tv_sec = ticks / 1000;
  2082. X        tv.tv_usec = (ticks % 1000) * (1000000/1000);
  2083. X    }
  2084. X
  2085. X    FD_ZERO(&fdset);
  2086. X    FD_SET(0, &fdset);
  2087. X    return (select(1, &fdset, NULL, NULL, (ticks >= 0) ? &tv : NULL));
  2088. X#endif
  2089. X}
  2090. X
  2091. X    int 
  2092. Xremove(buf)
  2093. X#ifdef linux
  2094. X    const
  2095. X#endif
  2096. X            char *buf;
  2097. X{
  2098. X    return unlink(buf);
  2099. X}
  2100. X
  2101. X#ifdef WILD_CARDS
  2102. X/*
  2103. X * ExpandWildCard() - this code does wild-card pattern matching using the shell
  2104. X *
  2105. X * Mool: return 0 for success, 1 for error (you may loose some memory) and
  2106. X *       put an error message in *file.
  2107. X *
  2108. X * num_pat is number of input patterns
  2109. X * pat is array of pointers to input patterns
  2110. X * num_file is pointer to number of matched file names
  2111. X * file is pointer to array of pointers to matched file names
  2112. X * On Unix we do not check for files only yet
  2113. X * list_notfound is ignored
  2114. X */
  2115. X
  2116. Xextern char *mktemp __ARGS((char *));
  2117. X#ifndef SEEK_SET
  2118. X# define SEEK_SET 0
  2119. X#endif
  2120. X#ifndef SEEK_END
  2121. X# define SEEK_END 2
  2122. X#endif
  2123. X
  2124. X    int
  2125. XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
  2126. X    int             num_pat;
  2127. X    char          **pat;
  2128. X    int            *num_file;
  2129. X    char         ***file;
  2130. X    int                files_only;
  2131. X    int                list_notfound;
  2132. X{
  2133. X    char    tmpname[TMPNAMELEN];
  2134. X    char    *command;
  2135. X    int        i;
  2136. X    size_t    len;
  2137. X    FILE    *fd;
  2138. X    char    *buffer;
  2139. X    char    *p;
  2140. X
  2141. X    *num_file = 0;        /* default: no files found */
  2142. X    *file = (char **)"";
  2143. X
  2144. X/*
  2145. X * get a name for the temp file
  2146. X */
  2147. X    strcpy(tmpname, TMPNAME2);
  2148. X    if (*mktemp(tmpname) == NUL)
  2149. X    {
  2150. X        emsg(e_notmp);
  2151. X        return 1;
  2152. X    }
  2153. X
  2154. X/*
  2155. X * let the shell expand the patterns and write the result into the temp file
  2156. X */
  2157. X    len = TMPNAMELEN + 10;
  2158. X    for (i = 0; i < num_pat; ++i)        /* count the length of the patterns */
  2159. X        len += strlen(pat[i]) + 3;
  2160. X    command = (char *)alloc(len);
  2161. X    if (command == NULL)
  2162. X        return 1;
  2163. X    strcpy(command, "echo > ");            /* built the shell command */
  2164. X    strcat(command, tmpname);
  2165. X    for (i = 0; i < num_pat; ++i)
  2166. X    {
  2167. X        strcat(command, " \"");
  2168. X        strcat(command, pat[i]);
  2169. X        strcat(command, "\"");
  2170. X    }
  2171. X    i = call_shell(command, 0);                /* execute it */
  2172. X    free(command);
  2173. X    if (i)                                    /* call_shell failed */
  2174. X    {
  2175. X        remove(tmpname);
  2176. X        sleep(1);            /* give the user a chance to read error messages */
  2177. X        updateScreen(CLEAR);            /* probably messed up screen */
  2178. X        return 1;
  2179. X    }
  2180. X
  2181. X/*
  2182. X * read the names from the file into memory
  2183. X */
  2184. X     fd = fopen(tmpname, "r");
  2185. X    if (fd == NULL)
  2186. X    {
  2187. X        emsg(e_notopen);
  2188. X        return 1;
  2189. X    }
  2190. X    fseek(fd, 0L, SEEK_END);
  2191. X    len = ftell(fd);                /* get size of temp file */
  2192. X    fseek(fd, 0L, SEEK_SET);
  2193. X    buffer = (char *)alloc(len + 1);
  2194. X    if (buffer == NULL)
  2195. X    {
  2196. X        remove(tmpname);
  2197. X        fclose(fd);
  2198. X        return 1;
  2199. X    }
  2200. X    i = fread(buffer, 1, len, fd);
  2201. X    fclose(fd);
  2202. X    remove(tmpname);
  2203. X    if (i != len)
  2204. X    {
  2205. X        emsg(e_notread);
  2206. X        free(buffer);
  2207. X        return 1;
  2208. X    }
  2209. X    buffer[len] = '\n';                /* make sure the buffers ends in NL */
  2210. X
  2211. X    p = buffer;
  2212. X    for (i = 0; *p != '\n'; ++i)        /* get number of entries */
  2213. X    {
  2214. X        while (*p != ' ' && *p != '\n')    /* skip entry */
  2215. X            ++p;
  2216. X        skipspace(&p);                    /* skip to next entry */
  2217. X    }
  2218. X    *num_file = i;
  2219. X    *file = (char **)alloc(sizeof(char *) * i);
  2220. X    if (*file == NULL)
  2221. X    {
  2222. X        free(buffer);
  2223. X        *file = (char **)"";
  2224. X        return 1;
  2225. X    }
  2226. X    p = buffer;
  2227. X    for (i = 0; i < *num_file; ++i)
  2228. X    {
  2229. X        (*file)[i] = p;
  2230. X        while (*p != ' ' && *p != '\n')
  2231. X            ++p;
  2232. X        if (*p == '\n')
  2233. X        {
  2234. X            *p = NUL;
  2235. X            break;
  2236. X        }
  2237. X        *p++ = NUL;
  2238. X        skipspace(&p);
  2239. X    }
  2240. X    return 0;
  2241. X}
  2242. X
  2243. X    void
  2244. XFreeWild(num, file)
  2245. X    int        num;
  2246. X    char    **file;
  2247. X{
  2248. X    if (file == NULL || num <= 0)
  2249. X        return;
  2250. X    free(file[0]);
  2251. X    free(file);
  2252. X}
  2253. X
  2254. X    int
  2255. Xhas_wildcard(p)
  2256. X    char *p;
  2257. X{
  2258. X    for ( ; *p; ++p)
  2259. X        if (strchr("*?[{`~$", *p) != NULL)
  2260. X            return 1;
  2261. X    return 0;
  2262. X}
  2263. X#endif    /* WILD_CARDS */
  2264. X
  2265. X#ifdef M_XENIX
  2266. X/*
  2267. X * Scaled-down version of rename, which is missing in Xenix.
  2268. X * This version can only move regular files and will fail if the
  2269. X * destination exists.
  2270. X */
  2271. X    int
  2272. Xrename(src, dst)
  2273. X    char *src, *dst;
  2274. X{
  2275. X    struct stat        st;
  2276. X
  2277. X    if (stat(dest, &st) >= 0)    /* fail if destination exists */
  2278. X        return -1;
  2279. X    if (link(src, dest) != 0)    /* link file to new name */
  2280. X        return -1;
  2281. X    if (unlink(src) == 0)        /* delete link to old name */
  2282. X        return 0;
  2283. X    return -1;
  2284. X}
  2285. X#endif /* M_XENIX */
  2286. END_OF_FILE
  2287. if test 15625 -ne `wc -c <'vim/src/unix.c'`; then
  2288.     echo shar: \"'vim/src/unix.c'\" unpacked with wrong size!
  2289. fi
  2290. # end of 'vim/src/unix.c'
  2291. fi
  2292. echo shar: End of archive 8 \(of 23\).
  2293. cp /dev/null ark8isdone
  2294. MISSING=""
  2295. 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
  2296.     if test ! -f ark${I}isdone ; then
  2297.     MISSING="${MISSING} ${I}"
  2298.     fi
  2299. done
  2300. if test "${MISSING}" = "" ; then
  2301.     echo You have unpacked all 23 archives.
  2302.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2303. else
  2304.     echo You still need to unpack the following archives:
  2305.     echo "        " ${MISSING}
  2306. fi
  2307. ##  End of shell archive.
  2308. exit 0
  2309. -------------8<----------------8<----------------8<---------------8<--------
  2310. Bram Moolenaar                             | DISCLAIMER:  This  note  does  not
  2311. Oce Nederland B.V., Research & Development | necessarily represent the position
  2312. p.o. box 101, 5900 MA  Venlo               | of  Oce-Nederland  B.V.  Therefore
  2313. The Netherlands        phone +31 77 594077 | no liability or responsibility for
  2314. UUCP: mool@oce.nl        fax +31 77 595450 | whatever will be accepted.
  2315.  
  2316. exit 0 # Just in case...
  2317.