home *** CD-ROM | disk | FTP | other *** search
- From: mool@oce.nl (Bram Moolenaar)
- Newsgroups: comp.sources.misc
- Subject: v44i036: vim - Vi IMproved editor, v3.0, Part17/26
- Date: 18 Aug 1994 14:03:00 -0500
- Organization: Sterling Software
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <330b94$e60@sparky.sterling.com>
- X-Md4-Signature: 53fa669384f024ab9c97b93695b199ea
-
- Submitted-by: mool@oce.nl (Bram Moolenaar)
- Posting-number: Volume 44, Issue 36
- Archive-name: vim/part17
- Environment: UNIX, AMIGA, MS-DOS, Windows NT
- Supersedes: vim: Volume 41, Issue 50-75
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: vim/macros/center.UU vim/src/amiga.c vim/src/edit.c
- # Wrapped by kent@sparky on Mon Aug 15 21:44:09 1994
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 17 (of 26)."'
- if test -f 'vim/macros/center.UU' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vim/macros/center.UU'\"
- else
- echo shar: Extracting \"'vim/macros/center.UU'\" \(270 characters\)
- sed "s/^X//" >'vim/macros/center.UU' <<'END_OF_FILE'
- Xbegin 644 vim/macros/center
- XM(E1H:7,@;6%C<F\@8V5N=&5R<R!A(&QI;F4@:6X@86X@.# @8VAA<F%C=&5R
- XM('-P86-E+@HB0V%R969U;#H@;&EN97,@;&]N9V5R('1H86X@.# @8VAA<F%C
- XM=&5R<R!W:6QL(&)E('1R=6YC871E9 IM87 @.V-E(#IS+UY;( E=*B\O#21M
- XB83@Q82 ;.#$6?$1@86QL9# Z<R\@("\@+V<-)' -:R1X"EY;
- X
- Xend
- END_OF_FILE
- if test 270 -ne `wc -c <'vim/macros/center.UU'`; then
- echo shar: \"'vim/macros/center.UU'\" unpacked with wrong size!
- else
- echo shar: Uudecoding \"'vim/macros/center'\" \(169 characters\)
- cat vim/macros/center.UU | uudecode
- if test 169 -ne `wc -c <'vim/macros/center'`; then
- echo shar: \"'vim/macros/center'\" uudecoded with wrong size!
- else
- rm vim/macros/center.UU
- fi
- fi
- # end of 'vim/macros/center.UU'
- fi
- if test -f 'vim/src/amiga.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vim/src/amiga.c'\"
- else
- echo shar: Extracting \"'vim/src/amiga.c'\" \(32474 characters\)
- sed "s/^X//" >'vim/src/amiga.c' <<'END_OF_FILE'
- X/* vi:ts=4:sw=4
- X *
- X * VIM - Vi IMproved by Bram Moolenaar
- X *
- X * Read the file "credits.txt" for a list of people who contributed.
- X * Read the file "uganda.txt" for copying and usage conditions.
- X */
- X
- X/*
- X * amiga.c
- X *
- X * Amiga system-dependent routines.
- X */
- X
- X#include "vim.h"
- X#include "globals.h"
- X#include "proto.h"
- X#include "param.h"
- X
- X#include <fcntl.h>
- X
- X#undef TRUE /* will be redefined by exec/types.h */
- X#undef FALSE
- X
- X#ifndef LATTICE
- X# include <exec/types.h>
- X# include <exec/exec.h>
- X# include <libraries/dos.h>
- X# include <libraries/dosextens.h>
- X# include <intuition/intuition.h>
- X#else
- X# include <proto/dos.h>
- X# include <libraries/dosextens.h>
- X# include <proto/intuition.h>
- X# include <proto/exec.h>
- X#endif
- X
- X#include <exec/memory.h>
- X
- X#ifndef NO_ARP
- X#include <libraries/arpbase.h> /* for arp.library */
- X#endif
- X#include <dos/dostags.h> /* for 2.0 functions */
- X#include <dos/dosasl.h>
- X
- X#if defined(LATTICE) && !defined(SASC) && !defined(NO_ARP)
- X# include <libraries/arp_pragmas.h>
- X#endif
- 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#ifndef AZTEC_C
- Xstatic long dos_packet __ARGS((struct MsgPort *, long, long));
- X#endif
- Xstatic int lock2name __ARGS((BPTR lock, char_u *buf, long len));
- Xstatic struct FileInfoBlock *get_fib __ARGS((char_u *));
- Xstatic int sortcmp __ARGS((char **a, char **b));
- X
- Xstatic BPTR raw_in = (BPTR)NULL;
- Xstatic BPTR raw_out = (BPTR)NULL;
- Xstatic int close_win = FALSE; /* set if Vim opened the window */
- X
- Xstruct IntuitionBase *IntuitionBase = NULL;
- X#ifndef NO_ARP
- Xstruct ArpBase *ArpBase = NULL;
- X#endif
- X
- Xstatic struct Window *wb_window;
- Xstatic char_u *oldwindowtitle = NULL;
- X
- X#ifndef NO_ARP
- Xint dos2 = FALSE; /* Amiga DOS 2.0x or higher */
- X#endif
- Xint size_set = FALSE; /* set to TRUE if window size was set */
- X
- X void
- Xwin_resize_on()
- X{
- X OUTSTRN("\033[12{");
- X}
- X
- X void
- Xwin_resize_off()
- X{
- X OUTSTRN("\033[12}");
- X}
- X
- X void
- Xmch_write(p, len)
- X char_u *p;
- X int len;
- X{
- X Write(raw_out, (char *)p, (long)len);
- X}
- X
- X/*
- X * GetChars(): low level input funcion.
- X * Get a characters from the keyboard.
- X * If time == 0 do not wait for characters.
- X * If time == n wait a short time for characters.
- X * If time == -1 wait forever for characters.
- X *
- X * Return number of characters read.
- X */
- X int
- XGetChars(buf, maxlen, time)
- X char_u *buf;
- X int maxlen;
- X int time; /* milli seconds */
- X{
- X int len;
- X long utime;
- X
- X if (time >= 0)
- X {
- X if (time == 0)
- X utime = 100L; /* time = 0 causes problems in DOS 1.2 */
- X else
- X utime = time * 1000L; /* convert from milli to micro secs */
- X if (WaitForChar(raw_in, utime) == 0) /* no character available */
- X return 0;
- X }
- X else /* time == -1 */
- X {
- X /*
- X * If there is no character available within 2 seconds (default)
- X * write the autoscript file to disk
- X */
- X if (WaitForChar(raw_in, p_ut * 1000L) == 0)
- X updatescript(0);
- X }
- X
- X for (;;) /* repeat until we got a character */
- X {
- X len = Read(raw_in, (char *)buf, (long)maxlen);
- X if (len > 0)
- X return len;
- X }
- X}
- X
- X/*
- X * return non-zero if a character is available
- X */
- X int
- Xmch_char_avail()
- X{
- X return (WaitForChar(raw_in, 100L) != 0);
- X}
- X
- X void
- Xsleep(n)
- X int n;
- X{
- X#ifndef LATTICE /* SAS declares void Delay(UNLONG) */
- X void Delay __ARGS((long));
- X#endif
- X
- X if (n > 0)
- X Delay((long)(50L * n));
- X}
- X
- X long
- Xmch_avail_mem(special)
- X int special;
- X{
- X return (long)AvailMem(special ? (long)MEMF_CHIP : (long)MEMF_ANY);
- X}
- X
- X void
- Xvim_delay()
- X{
- X Delay(25L);
- X}
- X
- X/*
- X * We have no job control, fake it by starting a new shell.
- X */
- Xvoid
- Xmch_suspend()
- X{
- X OUTSTR("new shell started\n");
- X (void)call_shell(NULL, 0, TRUE);
- X}
- X
- X#define DOS_LIBRARY ((UBYTE *) "dos.library")
- X
- X void
- Xmch_windinit()
- X{
- X static char intlibname[] = "intuition.library";
- X
- X#ifdef AZTEC_C
- X Enable_Abort = 0; /* disallow vim to be aborted */
- X#endif
- X Columns = 80;
- X Rows = 24;
- X
- X /*
- X * Set input and output channels, unless we have opened our own window
- X */
- X if (raw_in == (BPTR)NULL)
- X {
- X raw_in = Input();
- X raw_out = Output();
- X }
- X
- X flushbuf();
- X
- X wb_window = NULL;
- X if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)intlibname, 0L)) == NULL)
- X {
- X fprintf(stderr, "cannot open %s!?\n", intlibname);
- X mch_windexit(3);
- X }
- X (void)mch_get_winsize();
- X}
- X
- X#include <workbench/startup.h>
- 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) and -x we open our own window and disable :sh.
- X * Otherwise the compiler 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 int i;
- X BPTR nilfh, fh;
- X char_u buf1[20];
- X char_u buf2[BUF2SIZE];
- X static char_u *(constrings[3]) = {(char_u *)"con:0/0/662/210/",
- X (char_u *)"con:0/0/640/200/",
- X (char_u *)"con:0/0/320/200/"};
- X static char_u winerr[] = "VIM: Can't open window!\n";
- X struct WBArg *argp;
- X int ac;
- X char *av;
- X char_u *device = NULL;
- X int exitval = 4;
- X struct Library *DosBase;
- X int usewin = FALSE;
- X
- X/*
- X * check if we are running under DOS 2.0x or higher
- X */
- X if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
- X {
- X CloseLibrary(DosBase);
- X#ifndef NO_ARP
- X dos2 = TRUE;
- X#endif
- X }
- X else /* without arp functions we NEED 2.0 */
- X {
- X#ifdef NO_ARP
- X fprintf(stderr, "Need Amigados version 2.04 or later\n");
- X exit(3);
- X#else
- X /* need arp functions for dos 1.x */
- X if (!(ArpBase = (struct ArpBase *) OpenLibrary((UBYTE *)ArpName, ArpVersion)))
- X {
- X fprintf(stderr, "Need %s version %ld\n", ArpName, ArpVersion);
- X exit(3);
- X }
- X#endif
- X }
- X
- X/*
- X * scan argv[] for the '-e', '-x' and '-d' arguments
- X */
- X for (i = 1; i < argc; ++i)
- X if (argv[i][0] == '-')
- X {
- X switch (argv[i][1])
- X {
- X case 'e':
- X case 'x':
- X usewin = TRUE;
- X break;
- X
- X case 'd':
- X if (i < argc - 1)
- X device = (char_u *)argv[i + 1];
- X break;
- X }
- X }
- X
- X/*
- X * If we were not started from workbench, do not have a '-d' argument and
- X * we have been started with an interactive window, use that window.
- X */
- X if (argc != 0 && device == NULL &&
- X IsInteractive(Input()) && IsInteractive(Output()))
- X return;
- X
- X/*
- X * If we are in quickfix mode, we open our own window. We can't use the
- X * newcli trick below, because the compiler would not know when we are finished.
- X * We do the same with the '-x' option, for mail, rn, etc.
- X */
- X if (usewin)
- X {
- X /*
- X * Try to open a window. First try the specified device.
- X * Then try a 24 line 80 column window.
- X * If that fails, try two smaller ones.
- X */
- X for (i = -1; i < 3; ++i)
- X {
- X if (i >= 0)
- X device = constrings[i];
- X if (device && (raw_in = Open((UBYTE *)device, (long)MODE_NEWFILE)) != (BPTR)NULL)
- X break;
- X }
- X if (raw_in == (BPTR)NULL) /* all three failed */
- X {
- X fprintf(stderr, (char *)winerr);
- X goto exit;
- X }
- X raw_out = raw_in;
- X close_win = TRUE;
- X return;
- X }
- X
- X if ((nilfh = Open((UBYTE *)"NIL:", (long)MODE_NEWFILE)) == (BPTR)NULL)
- X {
- X fprintf(stderr, "Cannot open NIL:\n");
- X goto exit;
- X }
- X
- X /*
- X * make a unique name for the temp file (which we will not delete!)
- X */
- X sprintf((char *)buf1, "t:nc%ld", (char *)buf1); /* nobody else is using our stack */
- X if ((fh = Open((UBYTE *)buf1, (long)MODE_NEWFILE)) == (BPTR)NULL)
- X {
- X fprintf(stderr, "Cannot create %s\n", (char *)buf1);
- X goto exit;
- X }
- X /*
- X * Write the command into the file, put quotes around the arguments that
- X * have a space in them.
- X */
- X if (argc == 0) /* run from workbench */
- X ac = ((struct WBStartup *)argv)->sm_NumArgs;
- X else
- X ac = argc;
- X for (i = 0; i < ac; ++i)
- X {
- X if (argc == 0)
- X {
- X *buf2 = NUL;
- X argp = &(((struct WBStartup *)argv)->sm_ArgList[i]);
- X if (argp->wa_Lock)
- X (void)lock2name(argp->wa_Lock, buf2, (long)(BUF2SIZE - 1));
- X#ifndef NO_ARP
- X if (dos2) /* use 2.0 function */
- X#endif
- X AddPart((UBYTE *)buf2, (UBYTE *)argp->wa_Name, (long)(BUF2SIZE - 1));
- X#ifndef NO_ARP
- X else /* use arp function */
- X TackOn((char *)buf2, argp->wa_Name);
- X#endif
- X av = (char *)buf2;
- X }
- X else
- X av = argv[i];
- X
- X if (av[0] == '-' && av[1] == 'd') /* skip '-d' option */
- X {
- X ++i;
- X continue;
- X }
- X if (strchr(av, ' '))
- X Write(fh, "\"", 1L);
- X Write(fh, av, (long)strlen(av));
- X if (strchr(av, ' '))
- X Write(fh, "\"", 1L);
- X Write(fh, " ", 1L);
- X }
- X Write(fh, "\nendcli\n", 8L);
- X Close(fh);
- X
- X/*
- X * Try to open a new cli in a window. If '-d' argument was given try to open
- X * the specified device. Then try a 24 line 80 column window.
- X * If that fails, try two smaller ones.
- X */
- X for (i = -1; i < 3; ++i)
- X {
- X if (i >= 0)
- X device = constrings[i];
- X else if (device == NULL)
- X continue;
- X sprintf((char *)buf2, "newcli <nil: >nil: %s from %s", (char *)device, (char *)buf1);
- X#ifndef NO_ARP
- X if (dos2)
- X {
- X#endif
- X if (!SystemTags((UBYTE *)buf2, SYS_UserShell, TRUE, TAG_DONE))
- X break;
- X#ifndef NO_ARP
- X }
- X else
- X {
- X if (Execute((UBYTE *)buf2, nilfh, nilfh))
- X break;
- X }
- X#endif
- X }
- X if (i == 3) /* all three failed */
- X {
- X DeleteFile((UBYTE *)buf1);
- X fprintf(stderr, (char *)winerr);
- X goto exit;
- X }
- X exitval = 0; /* The Execute succeeded: exit this program */
- X
- Xexit:
- X#ifndef NO_ARP
- X if (ArpBase)
- X CloseLibrary((struct Library *) ArpBase);
- X#endif
- X exit(exitval);
- 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_u *name;
- X{
- X register struct FileInfoBlock *fib;
- X register size_t len;
- X
- X fib = get_fib(name);
- X if (fib != NULL)
- X {
- X len = STRLEN(name);
- X if (len == strlen(fib->fib_FileName)) /* safety check */
- X memmove((char *)name, fib->fib_FileName, len);
- X free(fib);
- X }
- X}
- X
- X/*
- X * Get the FileInfoBlock for file "fname"
- X * The returned structure has to be free()d.
- X * Returns NULL on error.
- X */
- X static struct FileInfoBlock *
- Xget_fib(fname)
- X char_u *fname;
- X{
- X register BPTR flock;
- X register struct FileInfoBlock *fib;
- X
- X if (fname == NULL) /* safety check */
- X return NULL;
- X fib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
- X if (fib != NULL)
- X {
- X flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
- X if (flock == (BPTR)NULL || !Examine(flock, fib))
- X {
- X free(fib); /* in case of an error the memory is freed here */
- X fib = NULL;
- X }
- X if (flock)
- X UnLock(flock);
- X }
- X return fib;
- X}
- X
- X/*
- X * set the title of our window
- X * icon name is not set
- X */
- X void
- Xmch_settitle(title, icon)
- X char_u *title;
- X char_u *icon;
- X{
- X if (wb_window != NULL && title != NULL)
- X SetWindowTitles(wb_window, (UBYTE *)title, (UBYTE *)-1L);
- X}
- X
- X/*
- X * Restore the window/icon title.
- X * which is one of:
- X * 1 Just restore title
- X * 2 Just restore icon (which we don't have)
- X * 3 Restore title and icon (which we don't have)
- X */
- X void
- Xmch_restore_title(which)
- X int which;
- X{
- X mch_settitle((which & 1) ? oldwindowtitle : NULL, NULL);
- X}
- X
- X/*
- X * Get name of current directory into buffer 'buf' of length 'len' bytes.
- X * Return OK for success, FAIL for failure.
- X */
- X int
- Xvim_dirname(buf, len)
- X char_u *buf;
- X int len;
- X{
- X return FullName((char_u *)"", buf, len);
- X}
- X
- X/*
- X * get absolute filename into buffer 'buf' of length 'len' bytes
- X *
- X * return FAIL for failure, OK otherwise
- X */
- X int
- XFullName(fname, buf, len)
- X char_u *fname, *buf;
- X int len;
- X{
- X BPTR l;
- X int retval = FAIL;
- X int i;
- X
- X *buf = NUL;
- X if (fname == NULL) /* always fail */
- X return FAIL;
- X
- X if ((l = Lock((UBYTE *)fname, (long)ACCESS_READ)) != (BPTR)0)/* lock the file */
- X {
- X retval = lock2name(l, buf, (long)len);
- X UnLock(l);
- X }
- X else if (!isFullName(fname)) /* not a full path yet */
- X {
- X /*
- X * if cannot lock the file, try to lock the current directory and then
- X * concatenate the file name
- X */
- X if ((l = Lock((UBYTE *)"", (long)ACCESS_READ)) != (BPTR)NULL) /* lock current dir */
- X {
- X retval = lock2name(l, buf, (long)len);
- X UnLock(l);
- X if (retval == OK)
- X {
- X i = STRLEN(buf);
- X if (i < len - 1 && (i == 0 || buf[i - 1] != ':'))
- X buf[i++] = '/';
- X STRNCPY(buf + i, fname, (size_t)(len - i)); /* concatenate the fname */
- X }
- X }
- X }
- X if (retval == FAIL || *buf == 0 || *buf == ':')
- X STRCPY(buf, fname); /* something failed; use the filename */
- X return retval;
- X}
- X
- X/*
- X * return TRUE is fname is an absolute path name
- X */
- X int
- XisFullName(fname)
- X char_u *fname;
- X{
- X return (STRCHR(fname, ':') != NULL);
- X}
- X
- X/*
- X * Get the full filename from a lock. Use 2.0 function if possible, because
- X * the arp function has more restrictions on the path length.
- X *
- X * return FAIL for failure, OK otherwise
- X */
- X static int
- Xlock2name(lock, buf, len)
- X BPTR lock;
- X char_u *buf;
- X long len;
- X{
- X#ifndef NO_ARP
- X if (dos2) /* use 2.0 function */
- X#endif
- X return ((int)NameFromLock(lock, (UBYTE *)buf, len) ? OK : FAIL);
- X#ifndef NO_ARP
- X else /* use arp function */
- X return ((int)PathName(lock, (char *)buf, (long)(len/32)) ? OK : FAIL);
- X#endif
- X}
- X
- X/*
- X * get file permissions for 'name'
- X */
- X long
- Xgetperm(name)
- X char_u *name;
- X{
- X struct FileInfoBlock *fib;
- X long retval = -1;
- X
- X fib = get_fib(name);
- X if (fib != NULL)
- X {
- X retval = fib->fib_Protection;
- X free(fib);
- X }
- X return retval;
- X}
- X
- X/*
- X * set file permission for 'name' to 'perm'
- X *
- X * return FAIL for failure, OK otherwise
- X */
- X int
- Xsetperm(name, perm)
- X char_u *name;
- X long perm;
- X{
- X perm &= ~FIBF_ARCHIVE; /* reset archived bit */
- X return (SetProtection((UBYTE *)name, (long)perm) ? OK : FAIL);
- X}
- X
- X/*
- X * return FALSE if "name" is not a directory
- X * return TRUE if "name" is a directory.
- X * return -1 for error.
- X */
- X int
- Xisdir(name)
- X char_u *name;
- X{
- X struct FileInfoBlock *fib;
- X int retval = -1;
- X
- X fib = get_fib(name);
- X if (fib != NULL)
- X {
- X retval = ((fib->fib_DirEntryType >= 0) ? TRUE : FALSE);
- X free(fib);
- X }
- X return retval;
- X}
- X
- X/*
- X * Careful: mch_windexit() may be called before mch_windinit()!
- X */
- X void
- Xmch_windexit(r)
- X int r;
- X{
- X if (raw_in) /* put terminal in 'normal' mode */
- X {
- X settmode(0);
- X stoptermcap();
- X }
- X if (raw_out)
- X {
- X if (term_console)
- X {
- X win_resize_off(); /* window resize events de-activated */
- X if (size_set)
- X OUTSTR("\233t\233u"); /* reset window size (CSI t CSI u) */
- X }
- X flushbuf();
- X }
- X
- X mch_restore_title(3); /* restore window title */
- X
- X ml_close_all(); /* remove all memfiles */
- X
- X#ifndef NO_ARP
- X if (ArpBase)
- X CloseLibrary((struct Library *) ArpBase);
- X#endif
- X if (close_win)
- X Close(raw_in);
- X if (r)
- X printf("Vim exiting with %d\n", r); /* somehow this makes :cq work!? */
- X exit(r);
- X}
- X
- X/*
- X * This is a routine for setting a given stream to raw or cooked mode on the
- X * Amiga . This is useful when you are using Lattice C to produce programs
- X * that want to read single characters with the "getch()" or "fgetc" call.
- X *
- X * Written : 18-Jun-87 By Chuck McManis.
- X */
- X
- X#define MP(xx) ((struct MsgPort *)((struct FileHandle *) (BADDR(xx)))->fh_Type)
- X
- X/*
- X * Function mch_settmode() - Convert the specified file pointer to 'raw' or 'cooked'
- X * mode. This only works on TTY's.
- X *
- X * Raw: keeps DOS from translating keys for you, also (BIG WIN) it means
- X * getch() will return immediately rather than wait for a return. You
- X * lose editing features though.
- X *
- X * Cooked: This function returns the designate file pointer to it's normal,
- X * wait for a <CR> mode. This is exactly like raw() except that
- X * it sends a 0 to the console to make it back into a CON: from a RAW:
- X */
- X void
- Xmch_settmode(raw)
- X int raw;
- X{
- X if (dos_packet(MP(raw_in), (long)ACTION_SCREEN_MODE, raw ? -1L : 0L) == 0)
- X fprintf(stderr, "cannot change console mode ?!\n");
- X}
- X
- X/*
- X * set screen mode, always fails.
- X */
- X int
- Xmch_screenmode(arg)
- X char_u *arg;
- X{
- X EMSG("Screen mode setting not supported");
- X return FAIL;
- X}
- X
- X/*
- X * Code for this routine came from the following :
- X *
- X * ConPackets.c - C. Scheppner, A. Finkel, P. Lindsay CBM
- X * DOS packet example
- X * Requires 1.2
- X *
- X * Found on Fish Disk 56.
- X *
- X * Heavely modified by mool.
- X */
- X
- X#include <devices/conunit.h>
- X
- X/*
- X * try to get the real window size
- X * return FAIL for failure, OK otherwise
- X */
- X int
- Xmch_get_winsize()
- X{
- X struct ConUnit *conUnit;
- X char id_a[sizeof(struct InfoData) + 3];
- X struct InfoData *id;
- X
- X if (!term_console) /* not an amiga window */
- X return FAIL;
- X
- X /* insure longword alignment */
- X id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
- X
- X /*
- X * Should make console aware of real window size, not the one we set.
- X * Unfortunately, under DOS 2.0x this redraws the window and it
- X * is rarely needed, so we skip it now, unless we changed the size.
- X */
- X if (size_set)
- X OUTSTR("\233t\233u"); /* CSI t CSI u */
- X flushbuf();
- X
- X if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0 ||
- X (wb_window = (struct Window *)id->id_VolumeNode) == NULL)
- X {
- X /* it's not an amiga window, maybe aux device */
- X /* terminal type should be set */
- X term_console = FALSE;
- X return FAIL;
- X }
- X if (oldwindowtitle == NULL)
- X oldwindowtitle = (char_u *)wb_window->Title;
- X if (id->id_InUse == (BPTR)NULL)
- X {
- X fprintf(stderr, "mch_get_winsize: not a console??\n");
- X return FAIL;
- X }
- X conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
- X
- X /* get window size */
- X Rows = conUnit->cu_YMax + 1;
- X Columns = conUnit->cu_XMax + 1;
- X if (Rows < 0 || Rows > 200) /* cannot be an amiga window */
- X {
- X Columns = 80;
- X Rows = 24;
- X term_console = FALSE;
- X return FAIL;
- X }
- X check_winsize();
- X
- X return OK;
- X}
- X
- X/*
- X * try to set the real window size
- X */
- X void
- Xmch_set_winsize()
- X{
- X if (term_console)
- X {
- X size_set = TRUE;
- X outchar(CSI);
- X outnum((long)Rows);
- X outchar('t');
- X outchar(CSI);
- X outnum((long)Columns);
- X outchar('u');
- X flushbuf();
- X }
- X}
- X
- X#ifdef SETKEYMAP
- X/*
- X * load and activate a new keymap for our CLI - DOES NOT WORK -
- X * The problem is that after the setting of the keymap the input blocks
- X * But the new keymap works allright in another window.
- X * Tried but no improvement:
- X * - remembering the length, data and command fields in request->io_xxx
- X * - settmode(0) first, settmode(1) afterwards
- X * - putting the keymap directly in conunit structure
- X */
- X
- X#include <devices/keymap.h>
- X
- X void
- Xset_keymap(name)
- X char_u *name;
- X{
- X char id_a[sizeof(struct InfoData) + 3];
- X struct InfoData *id;
- X static struct KeyMap *old;
- X static BPTR segment = (BPTR)NULL;
- X struct IOStdReq *request;
- X int c;
- X
- X if (!term_console)
- X return;
- X
- X /* insure longword alignment */
- X id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
- X
- X if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0)
- X {
- X EMSG("dos_packet failed");
- X return;
- X }
- X if (id->id_InUse == (BPTR)NULL)
- X {
- X EMSG("not a console??");
- X return;
- X }
- X request = (struct IOStdReq *) id->id_InUse;
- X
- X if (segment != (BPTR)NULL) /* restore old keymap */
- X {
- X request->io_Command = CD_SETKEYMAP;
- X request->io_Length = sizeof(struct KeyMap);
- X request->io_Data = (APTR)old;
- X DoIO((struct IORequest *)request);
- X if (request->io_Error)
- X EMSG("Cannot reset keymap");
- X else /* no error, free the allocated memory */
- X {
- X UnLoadSeg(segment);
- X FreeMem(old, sizeof(struct KeyMap));
- X segment = (BPTR)NULL;
- X }
- X }
- X if (name != NULL)
- X {
- X segment = LoadSeg(name);
- X if (segment == (BPTR)NULL)
- X {
- X EMSG("Cannot open keymap file");
- X return;
- X }
- X old = (struct KeyMap *)AllocMem(sizeof(struct KeyMap), MEMF_PUBLIC);
- X if (old == NULL)
- X {
- X EMSG(e_outofmem);
- X UnLoadSeg(segment);
- X segment = (BPTR)NULL;
- X }
- X else
- X {
- X request->io_Command = CD_ASKKEYMAP;
- X request->io_Length = sizeof(struct KeyMap);
- X request->io_Data = (APTR)old;
- X DoIO((struct IORequest *)request);
- X if (request->io_Error)
- X {
- X EMSG("Cannot get old keymap");
- X UnLoadSeg(segment);
- X segment = (BPTR)NULL;
- X FreeMem(old, sizeof(struct KeyMap));
- X }
- X else
- X {
- X request->io_Command = CD_SETKEYMAP;
- X request->io_Length = sizeof(struct KeyMap);
- X request->io_Data = (APTR)((segment << 2) + 18);
- X DoIO((struct IORequest *)request);
- X if (request->io_Error)
- X EMSG("Cannot set keymap");
- X
- X /* test for blocking */
- X request->io_Command = CMD_READ;
- X request->io_Length = 1;
- X request->io_Data = (APTR)&c;
- X DoIO((struct IORequest *)request); /* BLOCK HERE! */
- X if (request->io_Error)
- X EMSG("Cannot set keymap");
- X }
- X }
- X }
- X}
- X#endif
- X
- X#ifndef AZTEC_C
- X/*
- X * Sendpacket.c
- X *
- X * An invaluable addition to your Amiga.lib file. This code sends a packet to
- X * the given message port. This makes working around DOS lots easier.
- X *
- X * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
- X * however that you may wish to add it to Amiga.Lib, to do so, compile it and
- X * say 'oml lib:amiga.lib -r sendpacket.o'
- X */
- X
- X/* #include <proto/exec.h> */
- X/* #include <proto/dos.h> */
- X#include <exec/memory.h>
- X
- X/*
- X * Function - dos_packet written by Phil Lindsay, Carolyn Scheppner, and Andy
- X * Finkel. This function will send a packet of the given type to the Message
- X * Port supplied.
- X */
- X
- X static long
- Xdos_packet(pid, action, arg)
- X struct MsgPort *pid; /* process indentifier ... (handlers message port) */
- X long action, /* packet type ... (what you want handler to do) */
- X arg; /* single argument */
- X{
- X# ifndef NO_ARP
- X struct MsgPort *replyport;
- X struct StandardPacket *packet;
- X long res1;
- X
- X if (dos2)
- X# endif
- X return DoPkt(pid, action, arg, 0L, 0L, 0L, 0L); /* use 2.0 function */
- X# ifndef NO_ARP
- X
- X replyport = (struct MsgPort *) CreatePort(NULL, 0); /* use arp function */
- X if (!replyport)
- X return (0);
- X
- X /* Allocate space for a packet, make it public and clear it */
- X packet = (struct StandardPacket *)
- X AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
- X if (!packet) {
- X DeletePort(replyport);
- X return (0);
- X }
- X packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
- X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
- X packet->sp_Pkt.dp_Port = replyport;
- X packet->sp_Pkt.dp_Type = action;
- X packet->sp_Pkt.dp_Arg1 = arg;
- X
- X PutMsg(pid, (struct Message *)packet); /* send packet */
- X
- X WaitPort(replyport);
- X GetMsg(replyport);
- X
- X res1 = packet->sp_Pkt.dp_Res1;
- X
- X FreeMem(packet, (long) sizeof(struct StandardPacket));
- X DeletePort(replyport);
- X
- X return (res1);
- X# endif
- X}
- X#endif
- X
- X/*
- X * call shell, return FAIL for failure, OK otherwise
- X */
- X int
- Xcall_shell(cmd, filter, cooked)
- X char_u *cmd;
- X int filter; /* if != 0: called by dofilter() */
- X int cooked;
- X{
- X BPTR mydir;
- X int x;
- X#ifndef LATTICE
- X int use_execute;
- X char_u *shellcmd = NULL;
- X char_u *shellarg;
- X#endif
- X int retval = OK;
- X
- X if (close_win)
- X {
- X /* if Vim opened a window: Executing a shell may cause crashes */
- X EMSG("Cannot execute shell with -e or -x option");
- X return FAIL;
- X }
- X
- X if (term_console)
- X win_resize_off(); /* window resize events de-activated */
- X flushbuf();
- X
- X if (cooked)
- X settmode(0); /* set to cooked mode */
- X mydir = Lock((UBYTE *)"", (long)ACCESS_READ); /* remember current directory */
- X
- X#ifdef LATTICE /* not tested very much */
- X if (cmd == NULL)
- X {
- X# ifndef NO_ARP
- X if (dos2)
- X# endif
- X x = SystemTags(p_sh, SYS_UserShell, TRUE, TAG_DONE);
- X# ifndef NO_ARP
- X else
- X x = Execute(p_sh, raw_in, raw_out);
- X# endif
- X }
- X else
- X {
- X# ifndef NO_ARP
- X if (dos2)
- X# endif
- X x = SystemTags((char *)cmd, SYS_UserShell, TRUE, TAG_DONE);
- X# ifndef NO_ARP
- X else
- X x = Execute((char *)cmd, 0L, raw_out);
- X# endif
- X }
- X# ifdef NO_ARP
- X if (x < 0)
- X# else
- X if ((dos2 && x < 0) || (!dos2 && !x))
- X# endif
- X {
- X outstr((char_u *)"Cannot execute ");
- X if (cmd == NULL)
- X {
- X outstr((char_u *)"shell ");
- X outstr(p_sh);
- X }
- X else
- X outstr(cmd);
- X outchar('\n');
- X retval = FAIL;
- X }
- X# ifdef NO_ARP
- X else if (x)
- X# else
- X else if (!dos2 || x)
- X# endif
- X {
- X if (x = IoErr())
- X {
- X#ifdef WEBB_COMPLETE
- X if (!expand_interactively)
- X#endif
- X {
- X outchar('\n');
- X outnum(x);
- X outstr((char_u *)" returned\n");
- X }
- X retval = FAIL;
- X }
- X }
- X#else /* !LATTICE */
- X if (p_st >= 4 || (p_st >= 2 && !filter))
- X use_execute = 1;
- X else
- X use_execute = 0;
- X if (!use_execute)
- X {
- X /*
- X * separate shell name from argument
- X */
- X shellcmd = strsave(p_sh);
- X if (shellcmd == NULL) /* out of memory, use Execute */
- X use_execute = 1;
- X else
- X {
- X shellarg = shellcmd;
- X skiptospace(&shellarg); /* find start of arguments */
- X if (*shellarg != NUL)
- X {
- X *shellarg++ = NUL;
- X skipspace(&shellarg);
- X }
- X }
- X }
- X if (cmd == NULL)
- X {
- X if (use_execute)
- X {
- X# ifndef NO_ARP
- X if (dos2)
- X# endif
- X x = SystemTags((UBYTE *)p_sh, SYS_UserShell, TRUE, TAG_DONE);
- X# ifndef NO_ARP
- X else
- X x = !Execute((UBYTE *)p_sh, raw_in, raw_out);
- X# endif
- X }
- X else
- X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, NULL);
- X }
- X else if (use_execute)
- X {
- X# ifndef NO_ARP
- X if (dos2)
- X# endif
- X x = SystemTags((UBYTE *)cmd, SYS_UserShell, TRUE, TAG_DONE);
- X# ifndef NO_ARP
- X else
- X x = !Execute((UBYTE *)cmd, 0L, raw_out);
- X# endif
- X }
- X else if (p_st & 1)
- X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, (char *)cmd, NULL);
- X else
- X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, "-c", (char *)cmd, NULL);
- X# ifdef NO_ARP
- X if (x < 0)
- X# else
- X if ((dos2 && x < 0) || (!dos2 && x))
- X# endif
- X {
- X outstr((char_u *)"Cannot execute ");
- X if (use_execute)
- X {
- X if (cmd == NULL)
- X outstr(p_sh);
- X else
- X outstr(cmd);
- X }
- X else
- X {
- X outstr((char_u *)"shell ");
- X outstr(shellcmd);
- X }
- X outchar('\n');
- X retval = FAIL;
- X }
- X else
- X {
- X if (use_execute)
- X {
- X# ifdef NO_ARP
- X if (x)
- X# else
- X if (!dos2 || x)
- X# endif
- X x = IoErr();
- X }
- X else
- X x = wait();
- X if (x)
- X {
- X#ifdef WEBB_COMPLETE
- X if (!expand_interactively)
- X#endif
- X {
- X outchar('\n');
- X outnum((long)x);
- X outstrn((char_u *)" returned\n");
- X }
- X retval = FAIL;
- X }
- X }
- X free(shellcmd);
- X#endif /* !LATTICE */
- X
- X if (mydir = CurrentDir(mydir)) /* make sure we stay in the same directory */
- X UnLock(mydir);
- X if (cooked)
- X settmode(1); /* set to raw mode */
- X resettitle();
- X if (term_console)
- X win_resize_on(); /* window resize events activated */
- X return retval;
- X}
- X
- X/*
- X * check for an "interrupt signal"
- X * We only react to a CTRL-C, but also clear the other break signals to avoid trouble
- X * with lattice-c programs.
- X */
- X void
- Xbreakcheck()
- X{
- X if (SetSignal(0L, (long)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) & SIGBREAKF_CTRL_C)
- X got_int = TRUE;
- X}
- X
- X/* this routine causes manx to use this Chk_Abort() rather than it's own */
- X/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
- X/* is zero). Since we want to check for our own ^C's */
- X
- X#ifdef _DCC
- X#define Chk_Abort chkabort
- X#endif
- X
- X long
- XChk_Abort()
- X{
- X return(0L);
- X}
- X
- X/*
- X * ExpandWildCard() - this code does wild-card pattern matching using the arp
- X * routines. This is based on WildDemo2.c (found in arp1.1
- X * distribution). That code's copyright follows :
- X *-------------------------------------------------------------------------
- X * WildDemo2.c - Search filesystem for patterns, and separate into directories
- X * and files, sorting each separately using DA lists.
- X *
- X * -+=SDB=+-
- X *
- X * Copyright (c) 1987, Scott Ballantyne
- X * Use and abuse as you please.
- 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 * if file_only is TRUE we match only files, no dirs
- X * if list_notfound is TRUE we include not-found entries (probably locked)
- X * return OK for success, FAIL for error (you may loose some memory)
- X *-------------------------------------------------------------------------
- X */
- X
- X/* #include <arpfunctions.h> */
- Xextern void *malloc __ARGS((size_t)), *calloc __ARGS((size_t, size_t));
- Xstatic int insfile __ARGS((char_u *, int));
- Xstatic void freefiles __ARGS((void));
- X
- X#define ANCHOR_BUF_SIZE (512)
- X#define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE)
- X
- X/*
- X * we use this structure to built a list of file names
- X */
- Xstruct onefile
- X{
- X struct onefile *next;
- X char_u name[1]; /* really longer */
- X} *namelist = NULL;
- X
- X/*
- X * insert one file into the list of file names
- X * return FAIL for failure
- X * return OK for success
- X */
- X static int
- Xinsfile(name, isdir)
- X char_u *name;
- X int isdir;
- X{
- X struct onefile *new;
- X
- X new = (struct onefile *)alloc((unsigned)(sizeof(struct onefile) + STRLEN(name) + isdir));
- X if (new == NULL)
- X return FAIL;
- X STRCPY(&(new->name[0]), name);
- X if (isdir)
- X STRCAT(&(new->name[0]), "/");
- X new->next = namelist;
- X namelist = new;
- X return OK;
- X}
- X
- X/*
- X * free a whole list of file names
- X */
- X static void
- Xfreefiles()
- X{
- X struct onefile *p;
- X
- X while (namelist)
- X {
- X p = namelist->next;
- X free(namelist);
- X namelist = p;
- X }
- X}
- X
- X static int
- Xsortcmp(a, b)
- X char **a, **b;
- X{
- X return strcmp(*a, *b);
- X}
- X
- X int
- XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
- X int num_pat;
- X char_u **pat;
- X int *num_file;
- X char_u ***file;
- X int files_only;
- X int list_notfound;
- X{
- X int i;
- X struct AnchorPath *Anchor;
- X int domatchend = FALSE;
- X LONG Result;
- X struct onefile *p;
- X char_u *errmsg = NULL;
- X char_u *starbuf, *sp, *dp;
- X int foundone;
- X
- X *num_file = 0;
- X *file = (char_u **)"";
- X
- X /* Get our AnchorBase */
- X Anchor = (struct AnchorPath *) calloc((size_t)1, (size_t)ANCHOR_SIZE);
- X if (!Anchor)
- X goto OUT_OF_MEMORY;
- X Anchor->ap_StrLen = ANCHOR_BUF_SIZE; /* ap_Length not supported anymore */
- X#ifdef APF_DODOT
- X Anchor->ap_Flags = APF_DODOT | APF_DOWILD; /* allow '.' for current dir */
- X#else
- X Anchor->ap_Flags = APF_DoDot | APF_DoWild; /* allow '.' for current dir */
- X#endif
- X
- X for (i = 0; i < num_pat; i++)
- X {
- X#ifndef NO_ARP
- X if (dos2)
- X {
- X#endif
- X /* hack to replace '*' by '#?' */
- X starbuf = alloc((unsigned)(2 * STRLEN(pat[i]) + 1)); /* maximum required */
- X if (starbuf == NULL)
- X goto OUT_OF_MEMORY;
- X for (sp = pat[i], dp = starbuf; *sp; ++sp)
- X {
- X if (*sp == '*')
- X {
- X *dp++ = '#';
- X *dp++ = '?';
- X }
- X else
- X *dp++ = *sp;
- X }
- X *dp = NUL;
- X Result = MatchFirst((UBYTE *)starbuf, Anchor);
- X free(starbuf);
- X#ifndef NO_ARP
- X }
- X else
- X Result = FindFirst((char *)pat[i], Anchor);
- X#endif
- X domatchend = TRUE;
- X foundone = FALSE;
- X while (Result == 0)
- X {
- X if (!files_only || Anchor->ap_Info.fib_DirEntryType < 0)
- X {
- X (*num_file)++;
- X if (insfile((char_u *)Anchor->ap_Buf, Anchor->ap_Info.fib_DirEntryType >= 0) == FAIL)
- X {
- XOUT_OF_MEMORY:
- X errmsg = (char_u *)"Out of memory";
- X goto Return;
- X }
- X foundone = TRUE;
- X }
- X#ifndef NO_ARP
- X if (dos2)
- X#endif
- X Result = MatchNext(Anchor);
- X#ifndef NO_ARP
- X else
- X Result = FindNext(Anchor);
- X#endif
- X }
- X if (Result == ERROR_BUFFER_OVERFLOW)
- X {
- X errmsg = (char_u *)"ANCHOR_BUF_SIZE too small.";
- X goto Return;
- X }
- X if (!foundone)
- X {
- X if (list_notfound) /* put object with error in list */
- X {
- X (*num_file)++;
- X if (insfile(pat[i], FALSE) == FAIL)
- X goto OUT_OF_MEMORY;
- X }
- X else if (Result != ERROR_OBJECT_NOT_FOUND && Result != ERROR_NO_MORE_ENTRIES)
- X {
- X errmsg = (char_u *)"I/O ERROR";
- X goto Return;
- X }
- X }
- X#ifndef NO_ARP
- X if (dos2)
- X#endif
- X MatchEnd(Anchor);
- X#ifndef NO_ARP
- X else
- X FreeAnchorChain(Anchor);
- X#endif
- X domatchend = FALSE;
- X }
- X
- X p = namelist;
- X if (p)
- X {
- X *file = (char_u **) malloc(sizeof(char_u *) * (*num_file));
- X if (*file == NULL)
- X goto OUT_OF_MEMORY;
- X for (i = *num_file - 1; p; p = p->next, --i)
- X {
- X (*file)[i] = (char_u *) malloc(STRLEN(p->name) + 1);
- X if ((*file)[i] == NULL)
- X goto OUT_OF_MEMORY;
- X STRCPY((*file)[i], p->name);
- X }
- X qsort((void *)*file, (size_t)*num_file, sizeof(char_u *), sortcmp);
- X }
- XReturn:
- X if (domatchend)
- X {
- X#ifndef NO_ARP
- X if (dos2)
- X#endif
- X MatchEnd(Anchor);
- X#ifndef NO_ARP
- X else
- X FreeAnchorChain(Anchor);
- X#endif
- X }
- X if (Anchor)
- X free(Anchor);
- X freefiles();
- X if (errmsg)
- X {
- X emsg(errmsg);
- X *num_file = 0;
- X return FAIL;
- X }
- X return OK;
- X}
- X
- X void
- XFreeWild(num, file)
- X int num;
- X char_u **file;
- X{
- X if (file == NULL || num == 0)
- X return;
- X while (num--)
- X free(file[num]);
- X free(file);
- X}
- X
- X int
- Xhas_wildcard(p)
- X char_u *p;
- X{
- X for ( ; *p; ++p)
- X if (strchr("*?[(~#", *p) != NULL)
- X return TRUE;
- X return FALSE;
- X}
- X
- X/*
- X * With 2.0 support for reading local environment variables
- X * Careful: uses IObuff!
- X */
- X
- X char_u *
- Xvimgetenv(var)
- X char_u *var;
- X{
- X int len;
- X
- X#ifndef NO_ARP
- X if (!dos2)
- X return (char_u *)getenv((char *)var);
- X#endif
- X
- X len = GetVar((UBYTE *)var, (UBYTE *)IObuff, (long)(IOSIZE - 1), (long)0);
- X
- X if (len == -1)
- X return NULL;
- X else
- X return IObuff;
- X}
- END_OF_FILE
- if test 32474 -ne `wc -c <'vim/src/amiga.c'`; then
- echo shar: \"'vim/src/amiga.c'\" unpacked with wrong size!
- fi
- # end of 'vim/src/amiga.c'
- fi
- 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'\" \(31932 characters\)
- sed "s/^X//" >'vim/src/edit.c' <<'END_OF_FILE'
- X/* vi:ts=4:sw=4
- X *
- X * VIM - Vi IMproved by Bram Moolenaar
- X *
- X * Read the file "credits.txt" for a list of people who contributed.
- X * Read the file "uganda.txt" for copying and usage conditions.
- 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 char_u *get_inserted();
- Xstatic void start_arrow __ARGS((void));
- Xstatic void stop_arrow __ARGS((void));
- Xstatic void stop_insert __ARGS((void));
- Xstatic int echeck_abbr __ARGS((int));
- 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 = 0; /* call edit when next command finished */
- Xstatic char_u *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 int c;
- X int cc;
- X char_u *ptr;
- X char_u *saved_line = NULL; /* saved line for replace mode */
- X linenr_t saved_lnum = 0; /* lnum of saved line */
- X int saved_char = NUL; /* char replaced by NL */
- X linenr_t lnum;
- X int temp = 0;
- X int mode;
- X int nextc = 0;
- X int lastc = 0;
- X colnr_t mincol;
- X static linenr_t o_lnum = 0;
- X static int o_eol = FALSE;
- X#ifdef WEBB_KEYWORD_COMPL
- X FPOS complete_pos;
- X FPOS first_match;
- X char_u *complete_pat = NULL;
- X char_u *completion_str = NULL;
- X char_u *last_completion_str = NULL;
- X char_u *tmp_ptr;
- X int previous_c = 0;
- X int complete_col = 0; /* init for gcc */
- X int complete_direction;
- X int complete_any_word = 0; /* true -> ^N/^P hit with no prefix
- X * init for gcc */
- X int done;
- X int found_error = FALSE;
- X char_u backup_char = 0; /* init for gcc */
- X
- X c = NUL;
- X#endif /* WEBB_KEYWORD_COMPL */
- X
- X if (restart_edit)
- X {
- X arrow_used = TRUE;
- X restart_edit = 0;
- X /*
- X * If the cursor was after the end-of-line before the CTRL-O
- X * and it is now at the end-of-line, put it after the end-of-line
- X * (this is not correct in very rare cases).
- X */
- X if (o_eol && curwin->w_cursor.lnum == o_lnum &&
- X *((ptr = ml_get(curwin->w_cursor.lnum)) + curwin->w_cursor.col) != NUL &&
- X *(ptr + curwin->w_cursor.col + 1) == NUL)
- X ++curwin->w_cursor.col;
- X }
- X else
- X {
- X arrow_used = FALSE;
- X o_eol = FALSE;
- X }
- X
- X#ifdef DIGRAPHS
- X dodigraph(-1); /* clear digraphs */
- X#endif
- 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(ptr);
- X free(ptr);
- X
- X old_indent = 0;
- X
- X for (;;)
- X {
- X if (arrow_used) /* don't repeat insert when arrow key used */
- X count = 0;
- X
- X if (!arrow_used)
- X curwin->w_set_curswant = TRUE; /* set curwin->w_curswant for next K_DARROW or K_UARROW */
- X cursupdate(); /* Figure out where the cursor is based on curwin->w_cursor. */
- X showruler(0);
- X setcursor();
- X#ifdef WEBB_KEYWORD_COMPL
- X previous_c = c;
- X#endif /* WEBB_KEYWORD_COMPL */
- X if (nextc) /* character remaining from CTRL-V */
- X {
- X c = nextc;
- X nextc = 0;
- X }
- X else
- X {
- X c = vgetc();
- X if (c == Ctrl('C'))
- X got_int = FALSE;
- X }
- X#ifdef WEBB_KEYWORD_COMPL
- X if (previous_c == Ctrl('N') || previous_c == Ctrl('P'))
- X {
- X /* Show error message from attempted keyword completion (probably
- X * 'Pattern not found') until another key is hit, then go back to
- X * showing what mode we are in.
- X */
- X showmode();
- X if (c != Ctrl('N') && c != Ctrl('P'))
- X {
- X /* Get here when we have finished typing a sequence of ^N and
- X * ^P. Free up memory that was used, and make sure we can redo
- X * the insert.
- X */
- X if (completion_str != NULL)
- X AppendToRedobuff(completion_str);
- X free(complete_pat);
- X free(completion_str);
- X free(last_completion_str);
- X complete_pat = completion_str = last_completion_str = NULL;
- X }
- X }
- X#endif /* WEBB_KEYWORD_COMPL */
- X if (c != Ctrl('D')) /* remember to detect ^^D and 0^D */
- X lastc = c;
- X
- X/*
- X * In replace mode a backspace puts the original text back.
- X * We save the current line to be able to do that.
- X * If characters are appended to the line, they will be deleted.
- X * If we start a new line (with CR) the saved line will be empty, thus
- X * the characters will be deleted.
- X * If we backspace over the new line, that line will be saved.
- X */
- X if (State == REPLACE && saved_lnum != curwin->w_cursor.lnum)
- X {
- X free(saved_line);
- X saved_line = strsave(ml_get(curwin->w_cursor.lnum));
- X saved_lnum = curwin->w_cursor.lnum;
- X }
- X
- X#ifdef DIGRAPHS
- X c = dodigraph(c);
- X#endif /* DIGRAPHS */
- X
- X if (c == Ctrl('V'))
- X {
- X screen_start();
- X screen_outchar('^', curwin->w_row, curwin->w_col);
- X AppendToRedobuff((char_u *)"\026"); /* CTRL-V */
- X cursupdate();
- X setcursor();
- X
- X c = get_literal(&nextc);
- X
- X insertchar(c);
- X continue;
- X }
- X switch (c) /* handle character in insert mode */
- X {
- X case Ctrl('O'): /* execute one command */
- X if (echeck_abbr(Ctrl('O') + 0x100))
- X break;
- X count = 0;
- X if (State == INSERT)
- X restart_edit = 'I';
- X else
- X restart_edit = 'R';
- X o_lnum = curwin->w_cursor.lnum;
- X o_eol = (gchar_cursor() == NUL);
- X goto doESCkey;
- X
- X case ESC: /* an escape ends input mode */
- X if (echeck_abbr(ESC + 0x100))
- X break;
- X /*FALLTHROUGH*/
- X
- X case Ctrl('C'):
- XdoESCkey:
- X if (!arrow_used)
- X {
- X AppendToRedobuff(ESC_STR);
- X
- X if (--count > 0) /* repeat what was typed */
- X {
- X (void)start_redo_ins();
- X continue;
- X }
- X stop_insert();
- X }
- X if (!restart_edit)
- X curwin->w_set_curswant = TRUE;
- X
- X /*
- X * The cursor should end up on the last inserted character.
- X */
- X if (curwin->w_cursor.col != 0 && (!restart_edit || gchar_cursor() == NUL) && !p_ri)
- X dec_cursor();
- X if (extraspace) /* did reverse replace in column 0 */
- X {
- X (void)delchar(FALSE);
- X updateline();
- X extraspace = FALSE;
- X }
- X State = NORMAL;
- X /* inchar() may have deleted the "INSERT" message */
- X if (Recording)
- X showmode();
- X else if (p_smd)
- X MSG("");
- X free(saved_line);
- X old_indent = 0;
- 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('R'):
- X if (insertbuf(vgetc()) == FAIL)
- X beep();
- X break;
- X
- X case Ctrl('B'): /* toggle reverse insert mode */
- X p_ri = !p_ri;
- X showmode();
- 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 AppendCharToRedobuff(c);
- X if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
- X {
- X --curwin->w_cursor.col;
- X (void)delchar(FALSE); /* delete the '^' or '0' */
- X if (lastc == '^')
- X old_indent = get_indent(); /* remember current indent */
- X
- X /* determine offset from first non-blank */
- X temp = curwin->w_cursor.col;
- X beginline(TRUE);
- X temp -= curwin->w_cursor.col;
- X set_indent(0, TRUE); /* remove all indent */
- X }
- X else
- X {
- Xins_indent:
- X /* determine offset from first non-blank */
- X temp = curwin->w_cursor.col;
- X beginline(TRUE);
- X temp -= curwin->w_cursor.col;
- X
- X shift_line(c == Ctrl('D'), TRUE, 1);
- X
- X /* try to put cursor on same character */
- X temp += curwin->w_cursor.col;
- X }
- X if (temp <= 0)
- X curwin->w_cursor.col = 0;
- X else
- X curwin->w_cursor.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 delete anything in an empty file */
- 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 (bufempty() || (!p_ri &&
- X ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col <= 0) ||
- X (p_bs < 2 && (arrow_used ||
- X (curwin->w_cursor.lnum == Insstart.lnum &&
- X curwin->w_cursor.col <= Insstart.col) ||
- X (curwin->w_cursor.col <= 0 && p_bs == 0))))))
- X {
- X beep();
- X goto redraw;
- X }
- X
- X stop_arrow();
- X if (p_ri)
- X inc_cursor();
- X if (curwin->w_cursor.col <= 0) /* delete newline! */
- X {
- X lnum = Insstart.lnum;
- X if (curwin->w_cursor.lnum == Insstart.lnum || p_ri)
- X {
- X if (!u_save((linenr_t)(curwin->w_cursor.lnum - 2), (linenr_t)(curwin->w_cursor.lnum + 1)))
- X goto redraw;
- X --Insstart.lnum;
- X Insstart.col = 0;
- X /* this is in xvim, why?
- X if (curbuf->b_p_ai)
- X for (ptr = ml_get(Insstart.lnum);
- X iswhite(*ptr++); Insstart.col++)
- X ; */
- X }
- X /* in replace mode, in the line we started replacing, we
- X only move the cursor */
- X if (State != REPLACE || curwin->w_cursor.lnum > lnum)
- X {
- X temp = gchar_cursor(); /* remember current char */
- X --curwin->w_cursor.lnum;
- X (void)dojoin(FALSE, TRUE);
- X if (temp == NUL && gchar_cursor() != NUL)
- X ++curwin->w_cursor.col;
- X if (saved_char) /* restore what NL replaced */
- X {
- X State = NORMAL; /* no replace for this char */
- X inschar(saved_char); /* but no showmatch */
- X State = REPLACE;
- X saved_char = NUL;
- X if (!p_ri)
- X dec_cursor();
- X }
- X else if (p_ri) /* in reverse mode */
- X saved_lnum = 0; /* save this line again */
- X }
- X else
- X dec_cursor();
- X did_ai = FALSE;
- X }
- X else
- X {
- X if (p_ri && State != REPLACE)
- X dec_cursor();
- X mincol = 0;
- X if (mode == 3 && !p_ri && curbuf->b_p_ai) /* keep indent */
- X {
- X temp = curwin->w_cursor.col;
- X beginline(TRUE);
- X if (curwin->w_cursor.col < temp)
- X mincol = curwin->w_cursor.col;
- X curwin->w_cursor.col = temp;
- X }
- X
- X /* delete upto starting point, start of line or previous word */
- X do
- X {
- X if (!p_ri)
- X dec_cursor();
- X
- X /* start of word? */
- X if (mode == 1 && !isspace(gchar_cursor()))
- X {
- X mode = 2;
- X temp = isidchar(gchar_cursor());
- X }
- X /* end of word? */
- X else if (mode == 2 && (isspace(cc = gchar_cursor()) || isidchar(cc) != temp))
- X {
- X if (!p_ri)
- X inc_cursor();
- X else if (State == REPLACE)
- X dec_cursor();
- X break;
- X }
- X if (State == REPLACE)
- X {
- X if (saved_line)
- X {
- X if (extraspace)
- X {
- X if ((int)STRLEN(ml_get(curwin->w_cursor.lnum)) - 1 > (int)STRLEN(saved_line))
- X (void)delchar(FALSE);
- X else
- X {
- X dec_cursor();
- X (void)delchar(FALSE);
- X extraspace = FALSE;
- X pchar_cursor(*saved_line);
- X }
- X }
- X else if (curwin->w_cursor.col < STRLEN(saved_line))
- X pchar_cursor(saved_line[curwin->w_cursor.col]);
- X else if (!p_ri)
- X (void)delchar(FALSE);
- X }
- X }
- X else /* State != REPLACE */
- X {
- X (void)delchar(FALSE);
- X if (p_ri && gchar_cursor() == NUL)
- X break;
- X }
- X if (mode == 0) /* just a single backspace */
- X break;
- X if (p_ri && State == REPLACE && inc_cursor())
- X break;
- X } while (p_ri || (curwin->w_cursor.col > mincol && (curwin->w_cursor.lnum != Insstart.lnum ||
- X curwin->w_cursor.col != Insstart.col)));
- X if (extraspace)
- X dec_cursor();
- X }
- X did_si = FALSE;
- X can_si = FALSE;
- X if (curwin->w_cursor.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 AppendCharToRedobuff(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'): /* delete word before cursor */
- X mode = 1;
- X goto dodel;
- X
- X case Ctrl('U'): /* delete inserted text in current line */
- X mode = 3;
- X goto dodel;
- X
- X case K_LARROW:
- X if (oneleft() == OK)
- X {
- X start_arrow();
- X }
- X /* if 'whichwrap' set for cursor in insert mode may go
- X * to previous line */
- X else if ((p_ww & 16) && curwin->w_cursor.lnum > 1)
- X {
- X start_arrow();
- X --(curwin->w_cursor.lnum);
- X coladvance(MAXCOL);
- X curwin->w_curswant = MAXCOL; /* so we stay at the end */
- X }
- X else
- X beep();
- X break;
- X
- X case K_SLARROW:
- X if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.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 (gchar_cursor() != NUL)
- X {
- X curwin->w_set_curswant = TRUE;
- X start_arrow();
- X ++curwin->w_cursor.col;
- X }
- X /* if 'whichwrap' set for cursor in insert mode may go
- X * to next line */
- X else if ((p_ww & 16) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
- X {
- X curwin->w_set_curswant = TRUE;
- X start_arrow();
- X ++curwin->w_cursor.lnum;
- X curwin->w_cursor.col = 0;
- X }
- X else
- X beep();
- X break;
- X
- X case K_SRARROW:
- X if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count || gchar_cursor() != NUL)
- X {
- X fwd_word(1L, 0, 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 (echeck_abbr(TAB + 0x100))
- X break;
- X if ((!curbuf->b_p_et && !(p_sta && inindent())) || (p_ri && State == REPLACE))
- X goto normalchar;
- X
- X AppendToRedobuff((char_u *)"\t");
- X
- X if (!curbuf->b_p_et) /* insert smart tab */
- X goto ins_indent;
- X
- X /* p_te set: expand a tab into spaces */
- X stop_arrow();
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X if (p_sta && inindent())
- X temp = (int)curbuf->b_p_sw;
- X else
- X temp = (int)curbuf->b_p_ts;
- X temp -= curwin->w_cursor.col % temp;
- X inschar(' '); /* delete one char in replace mode */
- X while (--temp)
- X insstr((char_u *)" "); /* insstr does not delete chars */
- X goto redraw;
- X
- X case CR:
- X case NL:
- X if (echeck_abbr(c + 0x100))
- X break;
- X stop_arrow();
- X if (State == REPLACE)
- X {
- X saved_char = gchar_cursor();
- X (void)delchar(FALSE);
- X }
- X /*
- X * When 'autoindent' set delete white space after the cursor.
- X * Vi does this, although it probably does it implicitly due
- X * to the way it does auto-indent -- webb.
- X */
- X if (curbuf->b_p_ai || curbuf->b_p_si)
- X while ((c = gchar_cursor()) == ' ' || c == TAB)
- X (void)delchar(FALSE);
- X
- X AppendToRedobuff(NL_STR);
- X if (!Opencmd(FORWARD, TRUE, State == INSERT))
- X goto doESCkey; /* out of memory */
- X if (p_ri)
- X {
- X dec_cursor();
- X if (State == REPLACE && curwin->w_cursor.col > 0)
- X dec_cursor();
- X }
- X break;
- X
- X#ifdef DIGRAPHS
- X case Ctrl('K'):
- X screen_start();
- X screen_outchar('?', curwin->w_row, curwin->w_col);
- X setcursor();
- X c = vgetc();
- X if (c != ESC)
- X {
- X if (charsize(c) == 1)
- X {
- X screen_start();
- X screen_outchar(c, curwin->w_row, curwin->w_col);
- X }
- X setcursor();
- X cc = vgetc();
- X if (cc != ESC)
- X {
- X AppendToRedobuff((char_u *)"\026"); /* CTRL-V */
- X c = getdigraph(c, cc, TRUE);
- X goto normalchar;
- X }
- X }
- X updateline();
- X goto doESCkey;
- X#endif /* DIGRAPHS */
- X
- X#ifdef WEBB_KEYWORD_COMPL
- X case Ctrl('P'): /* Do previous pattern completion */
- X case Ctrl('N'): /* Do next pattern completion */
- X if (c == Ctrl('P'))
- X complete_direction = BACKWARD;
- X else
- X complete_direction = FORWARD;
- X if (previous_c != Ctrl('N') && previous_c != Ctrl('P'))
- X {
- X /* First time we hit ^N or ^P (in a row, I mean) */
- X complete_pos = curwin->w_cursor;
- X ptr = ml_get(complete_pos.lnum);
- X complete_col = complete_pos.col;
- X temp = complete_col - 1;
- X if (temp < 0 || !isidchar(ptr[temp]))
- X {
- X complete_pat = strsave((char_u *)"\\<[a-zA-Z_]");
- X complete_any_word = TRUE;
- X }
- X else
- X {
- X while (temp >= 0 && isidchar(ptr[temp]))
- X temp--;
- X temp++;
- X complete_pat = alloc(curwin->w_cursor.col - temp + 3);
- X if (complete_pat != NULL)
- X sprintf((char *)complete_pat, "\\<%.*s",
- X (int)(curwin->w_cursor.col - temp), ptr + temp);
- X complete_any_word = FALSE;
- X }
- X last_completion_str = strsave((char_u *)" ");
- X }
- X else
- X {
- X /* This is not the first ^N or ^P we have hit in a row */
- X while (curwin->w_cursor.col != complete_col)
- X {
- X curwin->w_cursor.col--;
- X delchar(FALSE);
- X }
- X if (completion_str != NULL)
- X {
- X free(last_completion_str);
- X last_completion_str = strsave(completion_str);
- X }
- X }
- X if (complete_pat == NULL || last_completion_str == NULL)
- X {
- X found_error = TRUE;
- X break;
- X }
- X if (!complete_any_word)
- X {
- X ptr = ml_get(curwin->w_cursor.lnum);
- X backup_char = ptr[complete_col - 1];
- X ptr[complete_col - 1] = ' ';
- X }
- X done = FALSE;
- X found_error = FALSE;
- X first_match.lnum = 0;
- X keep_old_search_pattern = TRUE;
- X while (!done)
- X {
- X if (complete_direction == BACKWARD)
- X {
- X ptr = ml_get(complete_pos.lnum);
- X while (isidchar(ptr[complete_pos.col]))
- X complete_pos.col--;
- X complete_pos.col++;
- X }
- X if (!searchit(&complete_pos, complete_direction,
- X complete_pat, 1L, TRUE, TRUE))
- X {
- X found_error = TRUE;
- X break;
- X }
- X if (complete_any_word)
- X ptr = ml_get_pos(&complete_pos);
- X else
- X ptr = ml_get_pos(&complete_pos) + 1;
- X tmp_ptr = ptr;
- X temp = 1;
- X while (*tmp_ptr != NUL && isidchar(*tmp_ptr++))
- X temp++;
- X free (completion_str);
- X tmp_ptr = completion_str = alloc(temp);
- X if (completion_str == NULL)
- X {
- X found_error = TRUE;
- X break;
- X }
- X while (*ptr != NUL && isidchar(*ptr))
- X *(tmp_ptr++) = *(ptr++);
- X *tmp_ptr = NUL;
- X if (completion_str[0] != NUL &&
- X STRCMP(completion_str, last_completion_str) != 0)
- X done = TRUE;
- X else if (first_match.lnum == 0)
- X {
- X first_match.lnum = complete_pos.lnum;
- X first_match.col = complete_pos.col;
- X }
- X else if (complete_pos.lnum == first_match.lnum
- X && complete_pos.col == first_match.col)
- X {
- X if (completion_str[0] == NUL)
- X EMSG("Exact match only");
- X else
- X EMSG("No other matches");
- X done = TRUE;
- X }
- X }
- X if (!found_error)
- X insstr(completion_str);
- X if (!complete_any_word)
- X {
- X ptr = ml_get(curwin->w_cursor.lnum);
- X ptr[complete_col - 1] = backup_char;
- X }
- X keep_old_search_pattern = FALSE;
- X updateline();
- X break;
- X#endif /* WEBB_KEYWORD_COMPL */
- X
- X case Ctrl('Y'): /* copy from previous line */
- X lnum = curwin->w_cursor.lnum - 1;
- X goto copychar;
- X
- X case Ctrl('E'): /* copy from next line */
- X lnum = curwin->w_cursor.lnum + 1;
- Xcopychar:
- X if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
- X {
- X beep();
- X break;
- X }
- X
- X /* try to advance to the cursor column */
- X temp = 0;
- X ptr = ml_get(lnum);
- X while (temp < curwin->w_virtcol && *ptr)
- X temp += chartabsize(*ptr++, (long)temp);
- X
- X if (temp > curwin->w_virtcol)
- X --ptr;
- X if ((c = *ptr) == NUL)
- X {
- X beep();
- X break;
- X }
- X
- X /*FALLTHROUGH*/
- X default:
- Xnormalchar:
- X /*
- X * do some very smart indenting when entering '{' or '}' or '#'
- X */
- X if (curwin->w_cursor.col > 0 && ((can_si && c == '}') || (did_si && c == '{')))
- X {
- X FPOS *pos, old_pos;
- X int i;
- X
- X /* for '}' set indent equal to matching '{' */
- X if (c == '}' && (pos = showmatch('{')) != NULL)
- X {
- X old_pos = curwin->w_cursor;
- X curwin->w_cursor = *pos;
- X i = get_indent();
- X curwin->w_cursor = old_pos;
- X set_indent(i, TRUE);
- X }
- X else
- X shift_line(TRUE, TRUE, 1);
- X }
- X /* set indent of '#' always to 0 */
- X if (curwin->w_cursor.col > 0 && can_si && c == '#')
- X {
- X /* remember current indent for next line */
- X old_indent = get_indent();
- X set_indent(0, TRUE);
- X }
- X
- X if (isidchar(c) || !echeck_abbr(c))
- 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 int cc;
- X int nc;
- X int oldstate;
- X int i;
- X
- X oldstate = State;
- X State = NOMAPPING; /* next characters not mapped */
- X
- X if (got_int)
- X {
- X *nextc = NUL;
- X return Ctrl('C');
- 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 if (cc == K_ZERO) /* NUL is stored as NL */
- X cc = '\n';
- X }
- X else if (cc == 0) /* NUL is stored as NL */
- X cc = '\n';
- X
- X State = oldstate;
- X *nextc = nc;
- X got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */
- 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 haveto_redraw = FALSE;
- X int textwidth;
- X
- X stop_arrow();
- X
- X /*
- X * find out textwidth to be used:
- X * if 'textwidth' option is set, use it
- X * else if 'wrapmargin' option is set, use Columns - 'wrapmargin'
- X * if invalid value, us 0.
- X */
- X textwidth = curbuf->b_p_tw;
- X if (textwidth == 0 && curbuf->b_p_wm)
- X textwidth = Columns - curbuf->b_p_wm;
- X if (textwidth < 0)
- X textwidth = 0;
- X
- 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. If textwidth == 0 it does nothing.
- X * Don't do this if an existing character is being replaced.
- X */
- X if (c == NUL || !(isspace(c) || (State == REPLACE && *ml_get_cursor() != NUL)))
- X {
- X while (textwidth && curwin->w_virtcol >= textwidth)
- X {
- X int startcol; /* Cursor column at entry */
- X int wantcol; /* column at textwidth border */
- X int foundcol; /* column for start of word */
- X
- X if ((startcol = curwin->w_cursor.col) == 0)
- X break;
- X coladvance(textwidth); /* find column of textwidth border */
- X wantcol = curwin->w_cursor.col;
- X
- X curwin->w_cursor.col = startcol - 1;
- X foundcol = 0;
- X while (curwin->w_cursor.col > 0) /* find position to break at */
- X {
- X if (isspace(gchar_cursor()))
- X {
- X while (curwin->w_cursor.col > 0 && isspace(gchar_cursor()))
- X --curwin->w_cursor.col;
- X if (curwin->w_cursor.col == 0) /* only spaces in front of text */
- X break;
- X foundcol = curwin->w_cursor.col + 1;
- X if (curwin->w_cursor.col < wantcol)
- X break;
- X }
- X --curwin->w_cursor.col;
- X }
- X
- X if (foundcol == 0) /* no spaces, cannot break line */
- X {
- X curwin->w_cursor.col = startcol;
- X break;
- X }
- X curwin->w_cursor.col = foundcol; /* put cursor after pos. to break line */
- X startcol -= foundcol;
- X Opencmd(FORWARD, FALSE, FALSE);
- X while (isspace(gchar_cursor()) && startcol) /* delete blanks */
- X {
- X (void)delchar(FALSE);
- X --startcol; /* adjust cursor pos. */
- X }
- X curwin->w_cursor.col += startcol;
- X curs_columns(FALSE); /* update curwin->w_virtcol */
- X haveto_redraw = TRUE;
- X }
- X if (c == NUL) /* formatting only */
- X return;
- X if (haveto_redraw)
- X {
- X /*
- X * If the cursor ended up just below the screen we scroll up here
- X * to avoid a redraw of the whole screen in the most common cases.
- X */
- X if (curwin->w_cursor.lnum == curwin->w_botline && !curwin->w_empty_rows)
- X win_del_lines(curwin, 0, 1, TRUE, TRUE);
- X updateScreen(CURSUPD);
- X }
- 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 && !p_ri)
- X {
- X char_u 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 (textwidth == 0 || (curwin->w_virtcol += charsize(p[i - 1])) < textwidth) &&
- X !(!no_abbr && !isidchar(c) && isidchar(p[i - 1])))
- X p[i++] = vgetc();
- X#ifdef DIGRAPHS
- X dodigraph(-1); /* clear digraphs */
- X dodigraph(p[i-1]); /* may be the start of a digraph */
- X#endif
- X p[i] = '\0';
- X insstr(p);
- X AppendToRedobuff(p);
- X }
- X else
- X {
- X inschar(c);
- X AppendCharToRedobuff(c);
- X }
- X
- X /*
- X * TODO: If the cursor has shifted past the end of the screen, should
- X * adjust the screen display. Avoids extra redraw.
- X */
- X
- X updateline();
- 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_save_cursor(); /* errors are ignored! */
- X Insstart = curwin->w_cursor; /* new insertion starts here */
- X ResetRedobuff();
- X AppendToRedobuff((char_u *)"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 ml_replace(curwin->w_cursor.lnum, (char_u *)"", TRUE);
- X curwin->w_cursor.col = 0;
- X if (curwin->w_p_list) /* the deletion is only seen in list mode */
- X updateline();
- X }
- X did_ai = FALSE;
- X did_si = FALSE;
- X can_si = FALSE;
- X}
- X
- X/*
- X * move cursor to start of line
- X * if flag == TRUE move to first non-white
- X */
- X void
- Xbeginline(flag)
- X int flag;
- X{
- X curwin->w_cursor.col = 0;
- X if (flag)
- X {
- X register char_u *ptr;
- X
- X for (ptr = ml_get(curwin->w_cursor.lnum); iswhite(*ptr); ++ptr)
- X ++curwin->w_cursor.col;
- X }
- X curwin->w_set_curswant = TRUE;
- X}
- X
- X/*
- X * oneright oneleft onedown oneup
- X *
- X * Move one char {right,left,down,up}.
- X * Return OK when sucessful, FAIL when we hit a line of file boundary.
- X */
- X
- X int
- Xoneright()
- X{
- X char_u *ptr;
- X
- X ptr = ml_get_cursor();
- X if (*ptr++ == NUL || *ptr == NUL)
- X return FAIL;
- X curwin->w_set_curswant = TRUE;
- X ++curwin->w_cursor.col;
- X return OK;
- X}
- X
- X int
- Xoneleft()
- X{
- X if (curwin->w_cursor.col == 0)
- X return FAIL;
- X curwin->w_set_curswant = TRUE;
- X --curwin->w_cursor.col;
- X return OK;
- X}
- X
- X int
- Xoneup(n)
- X long n;
- X{
- X if (n != 0 && curwin->w_cursor.lnum == 1)
- X return FAIL;
- X if (n >= curwin->w_cursor.lnum)
- X curwin->w_cursor.lnum = 1;
- X else
- X curwin->w_cursor.lnum -= n;
- X
- X if (operator == NOP)
- X cursupdate(); /* make sure curwin->w_topline is valid */
- X
- X /* try to advance to the column we want to be at */
- X coladvance(curwin->w_curswant);
- X return OK;
- X}
- X
- X int
- Xonedown(n)
- X long n;
- X{
- X if (n != 0 && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
- X return FAIL;
- X curwin->w_cursor.lnum += n;
- X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
- X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- X
- X if (operator == NOP)
- X cursupdate(); /* make sure curwin->w_topline is valid */
- X
- X /* try to advance to the column we want to be at */
- X coladvance(curwin->w_curswant);
- X return OK;
- X}
- X
- X/*
- X * move screen 'count' pages up or down and update screen
- X *
- X * return FAIL for failure, OK otherwise
- X */
- X int
- Xonepage(dir, count)
- X int dir;
- X long count;
- X{
- X linenr_t lp;
- X long n;
- X
- X if (curbuf->b_ml.ml_line_count == 1) /* nothing to do */
- X return FAIL;
- X for ( ; count > 0; --count)
- X {
- X if (dir == FORWARD ? (curwin->w_topline >= curbuf->b_ml.ml_line_count - 1) : (curwin->w_topline == 1))
- X {
- X beep();
- X return FAIL;
- X }
- X if (dir == FORWARD)
- X {
- X if (curwin->w_botline > curbuf->b_ml.ml_line_count) /* at end of file */
- X curwin->w_topline = curbuf->b_ml.ml_line_count;
- X else if (plines(curwin->w_botline) >= curwin->w_height - 2 || /* next line is big */
- X curwin->w_botline - curwin->w_topline <= 3) /* just three lines on screen */
- X curwin->w_topline = curwin->w_botline;
- X else
- X curwin->w_topline = curwin->w_botline - 2;
- X curwin->w_cursor.lnum = curwin->w_topline;
- X if (count != 1)
- X comp_Botline(curwin);
- X }
- X else /* dir == BACKWARDS */
- X {
- X lp = curwin->w_topline;
- X /*
- X * If the first two lines on the screen are not too big, we keep
- X * them on the screen.
- X */
- X if ((n = plines(lp)) > curwin->w_height / 2)
- X --lp;
- X else if (lp < curbuf->b_ml.ml_line_count && n + plines(lp + 1) < curwin->w_height / 2)
- X ++lp;
- X curwin->w_cursor.lnum = lp;
- X n = 0;
- X while (n <= curwin->w_height && lp >= 1)
- X {
- X n += plines(lp);
- X --lp;
- X }
- X if (n <= curwin->w_height) /* at begin of file */
- X curwin->w_topline = 1;
- X else if (lp >= curwin->w_topline - 2) /* happens with very long lines */
- X {
- X --curwin->w_topline;
- X comp_Botline(curwin);
- X curwin->w_cursor.lnum = curwin->w_botline - 1;
- X }
- X else
- X curwin->w_topline = lp + 2;
- X }
- X }
- X beginline(TRUE);
- X updateScreen(VALID);
- X return OK;
- X}
- X
- X void
- Xstuff_inserted(c, count, no_esc)
- X int c;
- X long count;
- X int no_esc;
- X{
- X char_u *esc_ptr = NULL;
- X char_u *ptr;
- X
- X if (last_insert == NULL)
- X {
- X EMSG("No inserted text yet");
- X return;
- X }
- X if (c)
- X stuffcharReadbuff(c);
- X if (no_esc && (esc_ptr = (char_u *)STRRCHR(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(ptr);
- X while (--count > 0);
- X
- X if (no_esc && esc_ptr)
- X *esc_ptr = 27; /* put the ESC back */
- X}
- X
- X char_u *
- Xget_last_insert()
- X{
- X if (last_insert == NULL)
- X return NULL;
- X return last_insert + last_insert_skip;
- X}
- X
- X/*
- X * Check the word in front of the cursor for an abbreviation.
- X * Called when the non-id character "c" has been entered.
- X * When an abbreviation is recognized it is removed from the text and
- X * the replacement string is inserted in typestr, followed by "c".
- X */
- X static int
- Xecheck_abbr(c)
- X int c;
- X{
- X if (p_paste || no_abbr) /* no abbreviations or in paste mode */
- X return FALSE;
- X
- X return check_abbr(c, ml_get(curwin->w_cursor.lnum), curwin->w_cursor.col,
- X curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
- X}
- END_OF_FILE
- if test 31932 -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
- echo shar: End of archive 17 \(of 26\).
- cp /dev/null ark17isdone
- 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 24 25 26 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 26 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-