Compare commits
3 Commits
uecide-too
...
levee-edit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f33305f894 | ||
|
|
e834303650 | ||
|
|
476573dae6 |
@@ -241,6 +241,7 @@ file /bin/login
|
||||
mode 04755
|
||||
file /bin/lol
|
||||
file /bin/ls
|
||||
file /bin/lv
|
||||
file /bin/mail
|
||||
mode 04755
|
||||
file /bin/make
|
||||
@@ -781,6 +782,7 @@ file /share/man/cat1/id.0
|
||||
file /share/man/cat1/la.0
|
||||
file /share/man/cat1/lcc.0
|
||||
file /share/man/cat1/ld.0
|
||||
file /share/man/cat1/lv.0
|
||||
file /share/man/cat1/passwd.0
|
||||
file /share/man/cat1/printf.0
|
||||
file /share/man/cat1/ranlib.0
|
||||
|
||||
@@ -12,7 +12,7 @@ CFLAGS += -Werror
|
||||
# /bin
|
||||
SUBDIR = adb adc-demo aout ar as awk basic cc chflags chpass \
|
||||
cpp dc diff emg env fdisk find forth fstat glcdtest \
|
||||
hostname id la lcc lcpp ld ls login make man med \
|
||||
hostname id la lcc lcpp ld levee ls login make man med \
|
||||
more nm passwd picoc portio printf pwm \
|
||||
rdprof ranlib re renice retroforth scm setty sl \
|
||||
sed sh smallc smlrc stty sysctl test uname wiznet xargs \
|
||||
|
||||
1
src/cmd/levee/.gitignore
vendored
Normal file
1
src/cmd/levee/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
lv
|
||||
56
src/cmd/levee/Makefile
Normal file
56
src/cmd/levee/Makefile
Normal file
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Public Domain. 1995/03/13 - Steven Schultz
|
||||
#
|
||||
TOPSRC = $(shell cd ../../..; pwd)
|
||||
include $(TOPSRC)/target.mk
|
||||
|
||||
#CFLAGS += -Werror
|
||||
LIBS += -ltermcap
|
||||
|
||||
OBJS = blockio.o display.o editcor.o exec.o find.o \
|
||||
unixcall.o globals.o insert.o main.o misc.o \
|
||||
modify.o move.o ucsd.o undo.o wildargs.o \
|
||||
version.o
|
||||
MAN = lv.0
|
||||
|
||||
all: lv ${MAN}
|
||||
|
||||
lv: ${OBJS}
|
||||
${CC} ${LDFLAGS} -o lv.elf ${OBJS} ${LIBS}
|
||||
${OBJDUMP} -S lv.elf > lv.dis
|
||||
${SIZE} lv.elf
|
||||
${ELF2AOUT} lv.elf $@ && rm lv.elf
|
||||
|
||||
version.o: version.c VERSION
|
||||
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
|
||||
|
||||
.SUFFIXES: .0 .1
|
||||
|
||||
.1.0:
|
||||
${MANROFF} $*.1 > $@
|
||||
|
||||
clean:
|
||||
rm -f *.o *.elf ${MAN} lv *.elf *.dis tags *~
|
||||
|
||||
install: all
|
||||
install lv ${DESTDIR}/bin/
|
||||
cp lv.0 ${DESTDIR}/share/man/cat1/
|
||||
|
||||
# Dependencies
|
||||
|
||||
blockio.o : levee.h extern.h blockio.c config.h
|
||||
display.o : levee.h extern.h termcap.i display.c config.h
|
||||
editcor.o : levee.h extern.h editcor.c config.h
|
||||
exec.o : levee.h extern.h exec.c config.h
|
||||
find.o : levee.h extern.h grep.h find.c config.h
|
||||
globals.o : levee.h globals.c config.h
|
||||
insert.o : levee.h extern.h insert.c config.h
|
||||
main.o : levee.h extern.h main.c config.h
|
||||
misc.o : levee.h extern.h misc.c config.h
|
||||
modify.o : levee.h extern.h grep.h modify.c config.h
|
||||
move.o : levee.h extern.h move.c config.h
|
||||
rmxcall.o : levee.h rmxcall.c config.h
|
||||
ucsd.o : levee.h extern.h ucsd.c config.h
|
||||
undo.o : levee.h extern.h undo.c config.h
|
||||
unixcall.o : levee.h extern.h unixcall.c config.h
|
||||
wildargs.o : levee.h extern.h wildargs.c config.h
|
||||
56
src/cmd/levee/Makefile-linux
Normal file
56
src/cmd/levee/Makefile-linux
Normal file
@@ -0,0 +1,56 @@
|
||||
# makefile for Levee
|
||||
|
||||
exedir=/usr/local/bin
|
||||
mandir=/usr/local/man
|
||||
CC=cc
|
||||
|
||||
CFLAGS=-g
|
||||
LDFLAGS=-g
|
||||
|
||||
OBJS = blockio.o display.o editcor.o exec.o find.o \
|
||||
unixcall.o globals.o insert.o main.o misc.o \
|
||||
modify.o move.o ucsd.o undo.o wildargs.o \
|
||||
version.o
|
||||
|
||||
lev: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o lev $(OBJS) -lcurses
|
||||
|
||||
version.o: version.c VERSION
|
||||
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
|
||||
|
||||
clean:
|
||||
rm -f *.o lev
|
||||
|
||||
distclean spotless: clean
|
||||
rm -f Makefile config.cmd config.sub config.h config.mak config.log config.md
|
||||
|
||||
install: install.bin install.man
|
||||
|
||||
install.bin: lev
|
||||
/home/sergev/Daily/workdir-2015-01-06/levee-3.5a/config.md $(PREFIX)$(exedir)
|
||||
/usr/bin/install -s -m 755 lev $(PREFIX)$(exedir)/levee
|
||||
/bin/ln -s -f levee $(PREFIX)$(exedir)/lv
|
||||
|
||||
install.man:
|
||||
/home/sergev/Daily/workdir-2015-01-06/levee-3.5a/config.md $(PREFIX)$(mandir)/man1
|
||||
/usr/bin/install -m 444 lv.1 $(PREFIX)$(mandir)/man1/levee.1
|
||||
echo ".so man1/levee.1" > $(PREFIX)$(mandir)/man1/lv.1
|
||||
|
||||
# Dependencies
|
||||
|
||||
blockio.o : levee.h extern.h blockio.c config.h
|
||||
display.o : levee.h extern.h termcap.i display.c config.h
|
||||
editcor.o : levee.h extern.h editcor.c config.h
|
||||
exec.o : levee.h extern.h exec.c config.h
|
||||
find.o : levee.h extern.h grep.h find.c config.h
|
||||
globals.o : levee.h globals.c config.h
|
||||
insert.o : levee.h extern.h insert.c config.h
|
||||
main.o : levee.h extern.h main.c config.h
|
||||
misc.o : levee.h extern.h misc.c config.h
|
||||
modify.o : levee.h extern.h grep.h modify.c config.h
|
||||
move.o : levee.h extern.h move.c config.h
|
||||
rmxcall.o : levee.h rmxcall.c config.h
|
||||
ucsd.o : levee.h extern.h ucsd.c config.h
|
||||
undo.o : levee.h extern.h undo.c config.h
|
||||
unixcall.o : levee.h extern.h unixcall.c config.h
|
||||
wildargs.o : levee.h extern.h wildargs.c config.h
|
||||
56
src/cmd/levee/Makefile.in
Normal file
56
src/cmd/levee/Makefile.in
Normal file
@@ -0,0 +1,56 @@
|
||||
# makefile for Levee
|
||||
|
||||
exedir=@exedir@
|
||||
mandir=@mandir@
|
||||
CC=@CC@
|
||||
|
||||
CFLAGS=@CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
|
||||
OBJS = blockio.o display.o editcor.o exec.o find.o \
|
||||
unixcall.o globals.o insert.o main.o misc.o \
|
||||
modify.o move.o ucsd.o undo.o wildargs.o \
|
||||
version.o
|
||||
|
||||
lev: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o lev $(OBJS) @LIBS@
|
||||
|
||||
version.o: version.c VERSION
|
||||
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
|
||||
|
||||
clean:
|
||||
rm -f *.o lev
|
||||
|
||||
distclean spotless: clean
|
||||
rm -f @GENERATED_FILES@ @CONFIGURE_FILES@
|
||||
|
||||
install: install.bin install.man
|
||||
|
||||
install.bin: lev
|
||||
@INSTALL_DIR@ $(PREFIX)$(exedir)
|
||||
@INSTALL_PROGRAM@ lev $(PREFIX)$(exedir)/levee
|
||||
@NOMK@@LN_S@ -f levee $(PREFIX)$(exedir)/lv
|
||||
|
||||
install.man:
|
||||
@INSTALL_DIR@ $(PREFIX)$(mandir)/man1
|
||||
@INSTALL_DATA@ lv.1 $(PREFIX)$(mandir)/man1/levee.1
|
||||
@NOMK@echo ".so man1/levee.1" > $(PREFIX)$(mandir)/man1/lv.1
|
||||
|
||||
# Dependencies
|
||||
|
||||
blockio.o : levee.h extern.h blockio.c config.h
|
||||
display.o : levee.h extern.h termcap.i display.c config.h
|
||||
editcor.o : levee.h extern.h editcor.c config.h
|
||||
exec.o : levee.h extern.h exec.c config.h
|
||||
find.o : levee.h extern.h grep.h find.c config.h
|
||||
globals.o : levee.h globals.c config.h
|
||||
insert.o : levee.h extern.h insert.c config.h
|
||||
main.o : levee.h extern.h main.c config.h
|
||||
misc.o : levee.h extern.h misc.c config.h
|
||||
modify.o : levee.h extern.h grep.h modify.c config.h
|
||||
move.o : levee.h extern.h move.c config.h
|
||||
rmxcall.o : levee.h rmxcall.c config.h
|
||||
ucsd.o : levee.h extern.h ucsd.c config.h
|
||||
undo.o : levee.h extern.h undo.c config.h
|
||||
unixcall.o : levee.h extern.h unixcall.c config.h
|
||||
wildargs.o : levee.h extern.h wildargs.c config.h
|
||||
1
src/cmd/levee/VERSION
Normal file
1
src/cmd/levee/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
3.5a
|
||||
48
src/cmd/levee/beep.c
Normal file
48
src/cmd/levee/beep.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#if OS_ATARI
|
||||
#include <atari\osbind.h>
|
||||
|
||||
char sound[] = {
|
||||
0xA8,0x01,0xA9,0x01,0xAA,0x01,0x00,
|
||||
0xF8,0x10,0x10,0x10,0x00,0x20,0x03
|
||||
};
|
||||
|
||||
#define SADDR 0xFF8800L
|
||||
|
||||
typedef char srdef[4];
|
||||
|
||||
srdef *SOUND = (srdef *)SADDR;
|
||||
|
||||
main()
|
||||
{
|
||||
register i;
|
||||
long ssp;
|
||||
|
||||
ssp = Super(0L);
|
||||
for (i=0; i<sizeof(sound); i++) {
|
||||
(*SOUND)[0] = i;
|
||||
(*SOUND)[2] = sound[i];
|
||||
}
|
||||
Super(ssp);
|
||||
}
|
||||
#endif /*OS_ATARI*/
|
||||
50
src/cmd/levee/blockio.c
Normal file
50
src/cmd/levee/blockio.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* read in a file -- return TRUE -- read file
|
||||
FALSE-- file too big
|
||||
*/
|
||||
|
||||
int PROC
|
||||
addfile(f, start, endd, size)
|
||||
FILE *f;
|
||||
int start;
|
||||
int endd, *size;
|
||||
{
|
||||
register int chunk;
|
||||
|
||||
chunk = read(fileno(f), core+start, (endd-start)-1);
|
||||
|
||||
*size = chunk;
|
||||
return chunk < (endd-start)-1;
|
||||
}
|
||||
|
||||
|
||||
/* write out a file -- return TRUE if ok. */
|
||||
|
||||
bool PROC
|
||||
putfile(f, start, endd)
|
||||
register FILE *f;
|
||||
register int start, endd;
|
||||
{
|
||||
return write(fileno(f), core+start, endd-start) == (endd-start);
|
||||
}
|
||||
26
src/cmd/levee/config.h
Normal file
26
src/cmd/levee/config.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* configuration for levee, generated Tue Jan 6 12:41:26 PST 2015
|
||||
* by sergev@ubuntu-sergev
|
||||
*/
|
||||
#ifndef __AC_LEVEE_D
|
||||
#define __AC_LEVEE_D 1
|
||||
|
||||
// Size of editor data buffer.
|
||||
#define SIZE 16000
|
||||
|
||||
#define OS_UNIX 1
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_MEMSET 1
|
||||
#define HAVE_STRCHR 1
|
||||
#define HAVE_BASENAME 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_TGETENT 1
|
||||
#define USE_TERMCAP 1
|
||||
#define HAVE_MVCUR 1
|
||||
#define mvcur __mvcur
|
||||
#define HAVE_TCGETATTR 1
|
||||
#define PATH_FIND "/bin/find"
|
||||
#define PATH_SED "/bin/sed"
|
||||
|
||||
#endif/* __AC_LEVEE_D */
|
||||
1219
src/cmd/levee/configure.inc
Executable file
1219
src/cmd/levee/configure.inc
Executable file
File diff suppressed because it is too large
Load Diff
112
src/cmd/levee/configure.sh
Executable file
112
src/cmd/levee/configure.sh
Executable file
@@ -0,0 +1,112 @@
|
||||
#! /bin/sh
|
||||
|
||||
# local options: ac_help is the help message that describes them
|
||||
# and LOCAL_AC_OPTIONS is the script that interprets them. LOCAL_AC_OPTIONS
|
||||
# is a script that's processed with eval, so you need to be very careful to
|
||||
# make certain that what you quote is what you want to quote.
|
||||
|
||||
ac_help="
|
||||
--use-termcap Link with termcap instead of curses, if possible
|
||||
--partial-install Don\'t install the lv, lv(1) name links
|
||||
--size=NNN Use a NNN-byte edit buffer
|
||||
--dos compile for ms-dos or microsoft windows
|
||||
--tos compile for the Atari ST
|
||||
--rmx compile for RMX
|
||||
--flexos compile for FlexOS"
|
||||
|
||||
LOCAL_AC_OPTIONS='
|
||||
case Z$1 in
|
||||
Z--partial-install)
|
||||
missing_lv=1;;
|
||||
Z--dos) ac_os=DOS;;
|
||||
Z--tos) ac_os=ATARI=1;;
|
||||
Z--flexos) ac_os=FLEXOS=1;;
|
||||
Z--rmx) ac_os=RMX;;
|
||||
Z--size=*) SIZE=$(echo Z$1 | sed -e 's/^Z--size=//') ;;
|
||||
*) ac_error=1;;
|
||||
esac;shift'
|
||||
|
||||
# load in the configuration file
|
||||
#
|
||||
TARGET=levee
|
||||
. ./configure.inc
|
||||
AC_INIT $TARGET
|
||||
|
||||
# validate --size=
|
||||
#
|
||||
case X"${SIZE}" in
|
||||
X[0-9][0-9]*) ;;
|
||||
X[0-9][0-9]*[Ll]);;
|
||||
X) ;;
|
||||
X*) AC_FAIL "--size=$SIZE is not a valid number" ;;
|
||||
esac
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
if [ "$OS_DOS" ]; then
|
||||
AC_DEFINE SIZE ${SIZE:-32000}
|
||||
AC_DEFINE PROC _fastcall
|
||||
AC_DEFINE TTY_ANSI 1
|
||||
AC_CHECK_FUNCS basename
|
||||
elif [ "$OS_ATARI" ]; then
|
||||
AC_DEFINE SIZE ${SIZE:-32000}
|
||||
AC_DEFINE TTY_VT52 1
|
||||
AC_DEFINE HAVE_BLKFILL 1
|
||||
AC_CHECK_FUNCS basename
|
||||
elif [ "$OS_FLEXOS" ]; then
|
||||
AC_DEFINE SIZE ${SIZE:-256000}
|
||||
AC_CHECK_FUNCS basename
|
||||
else
|
||||
AC_DEFINE SIZE ${SIZE:-256000}
|
||||
AC_DEFINE OS_UNIX 1
|
||||
|
||||
if AC_CHECK_HEADERS string.h; then
|
||||
# Assume a mainly ANSI-compliant world, where the
|
||||
# existance of string.h implies a memset() and strchr()
|
||||
AC_DEFINE HAVE_MEMSET 1
|
||||
AC_DEFINE HAVE_STRCHR 1
|
||||
else
|
||||
AC_CHECK_FUNCS memset
|
||||
AC_CHECK_FUNCS strchr
|
||||
fi
|
||||
|
||||
# for basename
|
||||
if AC_CHECK_FUNCS basename; then
|
||||
AC_CHECK_HEADERS libgen.h
|
||||
fi
|
||||
|
||||
if AC_CHECK_HEADERS signal.h; then
|
||||
# Assume a mainly sane world where the existance
|
||||
# of signal.h means that signal() exists
|
||||
AC_DEFINE HAVE_SIGNAL 1
|
||||
fi
|
||||
|
||||
if [ "$USE_TERMCAP" ]; then
|
||||
LIBORDER="-ltermcap -lcurses -lncurses"
|
||||
else
|
||||
LIBORDER="-lcurses -lncurses -ltermcap"
|
||||
fi
|
||||
|
||||
if AC_LIBRARY tgetent $LIBORDER; then
|
||||
AC_CHECK_HEADERS termcap.h || AC_FAIL "levee needs <termcap.h>"
|
||||
AC_DEFINE USE_TERMCAP 1
|
||||
# our -libtermcap might be (n)curses in disguise. If so,
|
||||
# it might have a colliding mvcur() that we need to define
|
||||
# ourselves out from.
|
||||
AC_QUIET AC_CHECK_FUNCS mvcur && AC_DEFINE mvcur __mvcur
|
||||
else
|
||||
# have to use a local termcap
|
||||
AC_DEFINE TERMCAP_EMULATION 1
|
||||
AC_DEFINE USE_TERMCAP 1
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS termios.h && AC_CHECK_FUNCS tcgetattr
|
||||
fi
|
||||
|
||||
if AC_PROG_LN_S && test -z "$missing_lv"; then
|
||||
AC_SUB NOMK ''
|
||||
else
|
||||
AC_SUB NOMK '@#'
|
||||
fi
|
||||
|
||||
AC_OUTPUT Makefile
|
||||
349
src/cmd/levee/display.c
Normal file
349
src/cmd/levee/display.c
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* do a gotoXY -- allowing -1 for same row/column */
|
||||
|
||||
#if USE_TERMCAP | OS_ATARI
|
||||
|
||||
#define MAXCOLS 160
|
||||
|
||||
#if USE_TERMCAP
|
||||
#include "termcap.i"
|
||||
#endif
|
||||
|
||||
#else /*!(USE_TERMCAP | OS_ATARI)*/
|
||||
|
||||
#define MAXCOLS COLS
|
||||
|
||||
#endif
|
||||
|
||||
VOID PROC
|
||||
mvcur(y,x)
|
||||
int y,x;
|
||||
{
|
||||
#if TERMCAP_EMULATION || TTY_ANSI
|
||||
static char gt[30];
|
||||
#endif
|
||||
|
||||
if (y == -1)
|
||||
y = curpos.y;
|
||||
else
|
||||
curpos.y = y;
|
||||
if (y >= LINES)
|
||||
y = LINES-1;
|
||||
if (x == -1)
|
||||
x = curpos.x;
|
||||
else
|
||||
curpos.x = x;
|
||||
if (x >= COLS)
|
||||
x = COLS-1;
|
||||
|
||||
#if TERMCAP_EMULATION
|
||||
tgoto(gt,y,x);
|
||||
strput(gt);
|
||||
#elif USE_TERMCAP
|
||||
strput( tgoto(CM, x, y) );
|
||||
#elif TTY_ZTERM
|
||||
zgoto(x,y);
|
||||
#elif TTY_ANSI
|
||||
{ register char *p = gt; /* make a ansi gotoXY string */
|
||||
*p++ = 033;
|
||||
*p++ = '[';
|
||||
numtoa(p,1+y); p += strlen(p);
|
||||
*p++ = ';';
|
||||
numtoa(p,1+x); p += strlen(p);
|
||||
*p++ = 'H';
|
||||
WRITE_TEXT(1, gt, (p-gt));
|
||||
}
|
||||
#elif TTY_VT52
|
||||
CM[2] = y+32;
|
||||
CM[3] = x+32;
|
||||
strput(CM);
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
numtoa(str,num)
|
||||
char *str;
|
||||
int num;
|
||||
{
|
||||
int i = 10; /* I sure hope that str is 10 bytes long... */
|
||||
bool neg = (num < 0);
|
||||
|
||||
if (neg)
|
||||
num = -num;
|
||||
|
||||
str[--i] = 0;
|
||||
do{
|
||||
str[--i] = (num%10)+'0';
|
||||
num /= 10;
|
||||
}while (num > 0);
|
||||
if (neg)
|
||||
str[--i] = '-';
|
||||
moveleft(&str[i], str, 10-i);
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
printi(num)
|
||||
int num;
|
||||
{
|
||||
char nb[10];
|
||||
register int size;
|
||||
|
||||
numtoa(nb,num);
|
||||
size = min(strlen(nb),COLS-curpos.x);
|
||||
if (size > 0) {
|
||||
nb[size] = 0;
|
||||
zwrite(nb, size);
|
||||
curpos.x += size;
|
||||
}
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
println()
|
||||
{
|
||||
zwrite("\r\n", 2);
|
||||
curpos.x = 0;
|
||||
curpos.y = min(curpos.y+1, LINES-1);
|
||||
}
|
||||
|
||||
/* print a character out in a readable form --
|
||||
* ^<x> for control-<x>
|
||||
* spaces for <tab>
|
||||
* normal for everything else
|
||||
*/
|
||||
|
||||
static char hexdig[] = "0123456789ABCDEF";
|
||||
|
||||
int PROC
|
||||
format(out,c)
|
||||
/* format: put a displayable version of c into out */
|
||||
register char *out;
|
||||
register unsigned c;
|
||||
{
|
||||
if (c >= ' ' && c < '') {
|
||||
out[0] = c;
|
||||
return 1;
|
||||
}
|
||||
else if (c == '\t' && !list) {
|
||||
register int i;
|
||||
int size;
|
||||
|
||||
for (i = size = tabsize - (curpos.x % tabsize);i > 0;)
|
||||
out[--i] = ' ';
|
||||
return size;
|
||||
}
|
||||
else if (c < 128) {
|
||||
out[0] = '^';
|
||||
out[1] = c^64;
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
#if OS_DOS
|
||||
out[0] = c;
|
||||
return 1;
|
||||
#else
|
||||
out[0] = '\\';
|
||||
out[1] = hexdig[(c>>4)&017];
|
||||
out[2] = hexdig[c&017];
|
||||
return 3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
printch(c)
|
||||
char c;
|
||||
{
|
||||
register int size;
|
||||
char buf[MAXCOLS];
|
||||
|
||||
size = min(format(buf,c),COLS-curpos.x);
|
||||
if (size > 0) {
|
||||
buf[size] = 0;
|
||||
zwrite(buf, size);
|
||||
curpos.x += size;
|
||||
}
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
prints(s)
|
||||
char *s;
|
||||
{
|
||||
int size,oxp = curpos.x;
|
||||
char buf[MAXCOLS+1];
|
||||
register int bi = 0;
|
||||
|
||||
while (*s && curpos.x < COLS) {
|
||||
size = format(&buf[bi],*s++);
|
||||
bi += size;
|
||||
curpos.x += size;
|
||||
}
|
||||
size = min(bi,COLS-oxp);
|
||||
if (size > 0) {
|
||||
buf[size] = 0;
|
||||
zwrite(buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
writeline(y,x,start)
|
||||
int y,x,start;
|
||||
{
|
||||
int endd,oxp;
|
||||
register int size;
|
||||
char buf[MAXCOLS+1];
|
||||
register int bi = 0;
|
||||
|
||||
endd = fseekeol(start);
|
||||
if (start==0 || core[start-1] == EOL)
|
||||
mvcur(y, 0);
|
||||
else
|
||||
mvcur(y, x);
|
||||
oxp = curpos.x;
|
||||
|
||||
while (start < endd && curpos.x < COLS) {
|
||||
size = format(&buf[bi],core[start++]);
|
||||
bi += size;
|
||||
curpos.x += size;
|
||||
}
|
||||
if (list) {
|
||||
buf[bi++] = '$';
|
||||
curpos.x++;
|
||||
}
|
||||
size = min(bi,COLS-oxp);
|
||||
if (size > 0) {
|
||||
buf[size] = 0;
|
||||
zwrite(buf, size);
|
||||
}
|
||||
if (curpos.x < COLS)
|
||||
strput(CE);
|
||||
}
|
||||
|
||||
/* redraw && refresh the screen */
|
||||
|
||||
VOID PROC
|
||||
refresh(y,x,start,endd,rest)
|
||||
int y,x,start,endd;
|
||||
bool rest;
|
||||
{
|
||||
int sp;
|
||||
|
||||
#if OS_ATARI
|
||||
/* turn the cursor off */
|
||||
asm(" clr.l -(sp) ");
|
||||
asm(" move.w #21,-(sp) ");
|
||||
asm(" trap #14 ");
|
||||
asm(" addq.l #6,sp ");
|
||||
#endif
|
||||
sp = start;
|
||||
while (sp <= endd) {
|
||||
writeline(y, x, sp);
|
||||
sp = 1+fseekeol(sp);
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
if (rest && sp >= bufmax)
|
||||
while (y<LINES-1) { /* fill screen with ~ */
|
||||
mvcur(y, 0);
|
||||
printch('~'); strput(CE);
|
||||
y++;
|
||||
}
|
||||
#if OS_ATARI
|
||||
/* turn the cursor back on */
|
||||
asm(" clr.w -(sp) ");
|
||||
asm(" move.w #1,-(sp) ");
|
||||
asm(" move.w #21,-(sp) ");
|
||||
asm(" trap #14 ");
|
||||
asm(" addq.l #6,sp ");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* redraw everything */
|
||||
|
||||
VOID PROC
|
||||
redisplay(flag)
|
||||
bool flag;
|
||||
{
|
||||
if (flag)
|
||||
clrprompt();
|
||||
refresh(0, 0, ptop, pend, TRUE);
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
scrollback(curr)
|
||||
int curr;
|
||||
{
|
||||
mvcur(0,0); /* move to the top line */
|
||||
do {
|
||||
ptop = bseekeol(ptop-1);
|
||||
strput(UpS);
|
||||
writeline(0, 0, ptop);
|
||||
} while (ptop > curr);
|
||||
setend();
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
scrollforward(curr)
|
||||
int curr;
|
||||
{
|
||||
do {
|
||||
writeline(LINES-1, 0, pend+1);
|
||||
zwrite("\n", 1);
|
||||
pend = fseekeol(pend+1);
|
||||
ptop = fseekeol(ptop)+1;
|
||||
} while (pend < curr);
|
||||
}
|
||||
|
||||
/* find if the number of lines between top && bottom is less than dofscroll */
|
||||
|
||||
bool PROC
|
||||
ok_to_scroll(top,bottom)
|
||||
int top,bottom;
|
||||
{
|
||||
int nl, i;
|
||||
|
||||
nl = dofscroll;
|
||||
i = top;
|
||||
do
|
||||
i += 1+scan(bufmax-i,'=',EOL, &core[i]);
|
||||
while (--nl > 0 && i < bottom);
|
||||
return(nl>0);
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
clrprompt()
|
||||
{
|
||||
mvcur(LINES-1,0);
|
||||
strput(CE);
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
prompt(toot,s)
|
||||
bool toot;
|
||||
char *s;
|
||||
{
|
||||
if (toot)
|
||||
error();
|
||||
clrprompt();
|
||||
prints(s);
|
||||
}
|
||||
50
src/cmd/levee/dos.asm
Normal file
50
src/cmd/levee/dos.asm
Normal file
@@ -0,0 +1,50 @@
|
||||
name dos
|
||||
page 55,80
|
||||
title 'DOS.ASM -- assembly routines for the teeny-shell under DOS'
|
||||
|
||||
_TEXT segment byte public 'CODE'
|
||||
|
||||
assume cs:_TEXT
|
||||
|
||||
public _fail_criterr
|
||||
;
|
||||
; If we get a critical error, just fail it - dos 3.0 and up only, please!
|
||||
;
|
||||
_fail_criterr proc far
|
||||
mov al, 3
|
||||
iret
|
||||
_fail_criterr endp
|
||||
|
||||
public _ignore_ctrlc
|
||||
;
|
||||
; If the user presses ^C, don't do any special handling of it.
|
||||
;
|
||||
_ignore_ctrlc proc far
|
||||
iret
|
||||
_ignore_ctrlc endp
|
||||
_pexec endp
|
||||
|
||||
public _intr_on_ctrlc
|
||||
;
|
||||
; If the user presses ^C, terminate the current process.
|
||||
;
|
||||
_intr_on_ctrlc proc far
|
||||
mov ah, 4ch
|
||||
mov al, 0ffh
|
||||
int 21h
|
||||
_intr_on_ctrlc endp
|
||||
|
||||
public _crawcin
|
||||
;
|
||||
; get a character from standard input without any sort of magical
|
||||
; processing.
|
||||
;
|
||||
_crawcin proc far
|
||||
mov ah, 07h
|
||||
int 21h
|
||||
ret
|
||||
_crawcin endp
|
||||
|
||||
_TEXT ends
|
||||
|
||||
end
|
||||
200
src/cmd/levee/doscall.c
Normal file
200
src/cmd/levee/doscall.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* dos interface for levee (Microsoft C)
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#if OS_DOS
|
||||
#include <glob.h>
|
||||
#include <dos.h>
|
||||
|
||||
int PROC
|
||||
min(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a>b) ? b : a;
|
||||
}
|
||||
|
||||
int PROC
|
||||
max(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a<b) ? b : a;
|
||||
}
|
||||
|
||||
PROC
|
||||
strput(s)
|
||||
char *s;
|
||||
{
|
||||
write(1, s, strlen(s));
|
||||
}
|
||||
|
||||
/* get a key, mapping certain control sequences
|
||||
*/
|
||||
PROC
|
||||
getKey()
|
||||
{
|
||||
register c;
|
||||
extern char _far crawcin();
|
||||
|
||||
c = crawcin();
|
||||
|
||||
if (c == 0 || c == 0xe0)
|
||||
switch (c=crawcin()) {
|
||||
case 'K': return LTARROW;
|
||||
case 'M': return RTARROW;
|
||||
case 'H': return UPARROW;
|
||||
case 'P': return DNARROW;
|
||||
case 'I': return 'U'-'@'; /* page-up */
|
||||
case 'Q': return 'D'-'@'; /* page-down */
|
||||
default : return 0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* don't allow interruptions to happen
|
||||
*/
|
||||
PROC
|
||||
nointr()
|
||||
{
|
||||
extern void _cdecl _interrupt _far ignore_ctrlc();
|
||||
_dos_setvect(0x23, ignore_ctrlc);
|
||||
} /* nointr */
|
||||
|
||||
|
||||
/* have ^C do what it usually does
|
||||
*/
|
||||
PROC
|
||||
allowintr()
|
||||
{
|
||||
extern void _cdecl _interrupt _far intr_on_ctrlc();
|
||||
_dos_setvect(0x23, intr_on_ctrlc);
|
||||
} /* allowintr */
|
||||
|
||||
|
||||
/*
|
||||
* basename() returns the filename part of a pathname
|
||||
*/
|
||||
char *
|
||||
basename(s)
|
||||
register char *s;
|
||||
{
|
||||
register char *p = s;
|
||||
|
||||
for (p = s+strlen(s); p > s; --p)
|
||||
if (p[-1] == '/' || p[-1] == '\\' || p[-1] == ':')
|
||||
return p;
|
||||
return s;
|
||||
} /* basename */
|
||||
|
||||
|
||||
/*
|
||||
* glob() expands a wildcard, via calls to _dos_findfirst/_next()
|
||||
* and pathname retention.
|
||||
*/
|
||||
char *
|
||||
glob(path, dta)
|
||||
char *path;
|
||||
struct glob_t *dta;
|
||||
{
|
||||
static char path_bfr[256]; /* full pathname to return */
|
||||
static char *file_part; /* points at file - for filling */
|
||||
static char isdotpattern; /* looking for files starting with . */
|
||||
static char isdotordotdot; /* special case . or .. */
|
||||
static struct glob_t *dta_bfr; /* pointer to desired dta */
|
||||
static struct find_t dird; /* DOS dta */
|
||||
|
||||
register st; /* status from _dos_findxxx */
|
||||
|
||||
if (path) {
|
||||
/* when we start searching, save the path part of the filename in
|
||||
* a safe place.
|
||||
*/
|
||||
strcpy(path_bfr, path);
|
||||
file_part = basename(path_bfr);
|
||||
|
||||
/* set up initial parameters for DosFindFirst()
|
||||
*/
|
||||
dta_bfr = dta;
|
||||
|
||||
if (isdotpattern = (*file_part == '.'))
|
||||
/* _dos_findfirst() magically expands . and .. into their
|
||||
* directory names. Admittedly, there are cases where
|
||||
* this can be useful, but this is not one of them. So,
|
||||
* if we find that we're matching . and .., we just
|
||||
* special-case ourselves into oblivion to get around
|
||||
* this particular bit of DOS silliness.
|
||||
*/
|
||||
isdotordotdot = (file_part[1] == 0 || file_part[1] == '.');
|
||||
else
|
||||
isdotordotdot = 0;
|
||||
|
||||
st = _dos_findfirst(path, 0x16, &dird);
|
||||
}
|
||||
else
|
||||
st = _dos_findnext(&dird);
|
||||
|
||||
while (st == 0) {
|
||||
/* Unless the pattern has a leading ., don't include any file
|
||||
* that starts with .
|
||||
*/
|
||||
if (dird.name[0] == '.' && !isdotpattern)
|
||||
st = _dos_findnext(&dird);
|
||||
else {
|
||||
/* found a file - affix the path leading to it, then return
|
||||
* a pointer to the (static) buffer holding the path+the name.
|
||||
*/
|
||||
strlwr(dird.name); /* DOS & OS/2 are case-insensitive */
|
||||
|
||||
if (dta_bfr) {
|
||||
dta_bfr->wr_time = dird.wr_time;
|
||||
dta_bfr->wr_date = dird.wr_date;
|
||||
if (isdotordotdot)
|
||||
strcpy(dta_bfr->name, file_part);
|
||||
else {
|
||||
strncpy(dta_bfr->name, dird.name, sizeof(dta_bfr->name)-1);
|
||||
dta_bfr->name[sizeof(dta_bfr->name)-1] = 0;
|
||||
}
|
||||
dta_bfr->size = dird.size;
|
||||
dta_bfr->attrib = dird.attrib;
|
||||
}
|
||||
if (!isdotordotdot)
|
||||
strcpy(file_part, dird.name);
|
||||
return path_bfr;
|
||||
}
|
||||
}
|
||||
/* nothing matched
|
||||
*/
|
||||
if (path && isdotordotdot) {
|
||||
/* must be at root, so statting dot will most likely fail. Fake a
|
||||
* dta.
|
||||
*/
|
||||
if (dta_bfr) {
|
||||
memset(dta_bfr, 0, sizeof *dta_bfr);
|
||||
dta_bfr->attrib = 0x10;
|
||||
dta_bfr->name[0] = '.';
|
||||
}
|
||||
return path_bfr;
|
||||
}
|
||||
return (char*)0;
|
||||
} /* glob */
|
||||
#endif /*OS_DOS*/
|
||||
644
src/cmd/levee/editcor.c
Normal file
644
src/cmd/levee/editcor.c
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2008 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/* do some undoable modification */
|
||||
|
||||
/* These variables make docommand nonrecursive */
|
||||
|
||||
bool ok;
|
||||
int newend, /* end position after change */
|
||||
disp, /* start redisplay here */
|
||||
newc, /* new cursor position for wierd cmds */
|
||||
endY; /* final yp for endp */
|
||||
|
||||
/* move a line of text right || left */
|
||||
|
||||
VOID PROC
|
||||
adjuster(sleft, endd, sw)
|
||||
bool sleft;
|
||||
int endd, sw;
|
||||
{
|
||||
bool noerror;
|
||||
int np, ts,
|
||||
ip,
|
||||
ss, adjp,
|
||||
DLEnum;
|
||||
|
||||
if (sw == -1)
|
||||
sw = shiftwidth;
|
||||
if (sleft)
|
||||
sw = -sw;
|
||||
curr = bseekeol(curr);
|
||||
ip = curr;
|
||||
noerror = TRUE;
|
||||
do {
|
||||
DLEnum = sw + findDLE(ip, &np, bufmax,0);
|
||||
if (DLEnum >= 0 && DLEnum <= COLS && core[np] != EOL && np < bufmax) {
|
||||
ts = DLEnum / tabsize;
|
||||
ss = DLEnum % tabsize;
|
||||
adjp = ts+ss+ip;
|
||||
if (np-adjp < 0) { /* expand the buf */
|
||||
moveright(&core[np], &core[adjp], bufmax-np);
|
||||
insert_to_undo(&undo, adjp, adjp - np);
|
||||
}
|
||||
else
|
||||
delete_to_undo(&undo, adjp, np - adjp);
|
||||
|
||||
endd += (adjp-np);
|
||||
noerror = move_to_undo(&undo, ip, ts+ss);
|
||||
fillchar(&core[ip], ts, TAB);
|
||||
fillchar(&core[ip+ts], ss, 32);
|
||||
}
|
||||
else if (np > ip) { /* remove the indent code */
|
||||
noerror = delete_to_undo(&undo, ip, np-ip);
|
||||
endd += (ip - np);
|
||||
}
|
||||
ip = 1 + fseekeol(ip);
|
||||
} while (noerror && ip < endd);
|
||||
if (!noerror)
|
||||
error();
|
||||
newc = skipws(curr);
|
||||
disp = curr;
|
||||
newend = endd;
|
||||
endY = setY(min(newend, pend));
|
||||
}
|
||||
|
||||
/* join <count> lines together */
|
||||
|
||||
VOID PROC
|
||||
join(count)
|
||||
int count;
|
||||
{
|
||||
bool ok;
|
||||
int lp, first;
|
||||
|
||||
if (lend < bufmax) { /* are we in the buffer? */
|
||||
disp = lend; /* start redraw here */
|
||||
newc = lend;
|
||||
do { /* join until.. */
|
||||
first = lend;
|
||||
lp = skipws(1+first);
|
||||
ok = delete_to_undo(&undo, 1+first, lp-(1+first));
|
||||
if (ok) {
|
||||
ok = move_to_undo(&undo, first, 1);
|
||||
core[first] = ' '; /* spaces between lines */
|
||||
}
|
||||
count--;
|
||||
lend = fseekeol(first);
|
||||
} while (ok && count > 0);
|
||||
endY = MAGICNUMBER;
|
||||
newend = lend;
|
||||
if (!ok)
|
||||
error();
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
squiggle(endp, c, dorepl)
|
||||
int endp;
|
||||
char c;
|
||||
bool dorepl;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (endp >= curr) {
|
||||
ok = move_to_undo(&undo,curr,endp-curr+1);
|
||||
if (ok) {
|
||||
for (i = curr;i<=endp;i++) {
|
||||
if (!dorepl) { /* squiggle it to uc - lc */
|
||||
if (core[i] >='A' && core[i] <='Z')
|
||||
core[i] += 32;
|
||||
else if (core[i]>='a' && core[i]<='z')
|
||||
core[i] -= 32;
|
||||
}
|
||||
else
|
||||
core[i] = c;
|
||||
}
|
||||
newend = min(endp+1,lend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
bigreplace()
|
||||
{
|
||||
int len, tsiz;
|
||||
|
||||
tsiz = lend-curr;
|
||||
if (move_to_undo(&undo, curr, tsiz))
|
||||
if (SIZE - bufmax > tsiz) { /* enough room for temp copy? */
|
||||
moveleft(&core[curr], &core[bufmax],lend-curr);
|
||||
if (line(core, curr, lend, &len) != ESC)
|
||||
error();
|
||||
newend = curr+len;
|
||||
moveright(&core[bufmax+len], &core[newend], lend-newend);
|
||||
}
|
||||
}
|
||||
|
||||
bool PROC
|
||||
put(before)
|
||||
bool before;
|
||||
{
|
||||
endY = setY(curr);
|
||||
if (!before)
|
||||
if (yank.lines)
|
||||
curr = min(lend+1,bufmax);
|
||||
else
|
||||
curr = min(curr+1, lend);
|
||||
else if (yank.lines)
|
||||
curr = lstart;
|
||||
newc = disp = curr;
|
||||
return(putback(curr, &newend));
|
||||
}
|
||||
|
||||
bool PROC
|
||||
execute(start, end)
|
||||
{
|
||||
int tf;
|
||||
FILE *f;
|
||||
char scratch[20];
|
||||
bool ret = FALSE;
|
||||
int size;
|
||||
|
||||
strcpy(scratch, "/tmp/lv.XXXXXX");
|
||||
|
||||
clrprompt();
|
||||
printch('!');
|
||||
if ( !getlin(instring) )
|
||||
return FALSE;
|
||||
|
||||
if ( (tf = mkstemp(scratch)) < 0 ) {
|
||||
prints("[tempfile error]");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strcat(instring, " 2>&1 <");
|
||||
strcat(instring, scratch);
|
||||
|
||||
if ( (size = write(tf, core+start, end-start)) == (end-start) ) {
|
||||
if ( (f=popen(instring, "r")) ) {
|
||||
if ( deletion(start, end) && (insertfile(f, 1, start, &size) > 0) )
|
||||
ret = TRUE;
|
||||
pclose(f);
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
close(tf);
|
||||
unlink(scratch);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
gcount()
|
||||
{
|
||||
do {
|
||||
count = (count*10) + (ch-'0');
|
||||
readchar(); /* get a char to replace the one we dumped */
|
||||
} while ( count >= 0 && isdigit(ch) );
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
docommand(cmd)
|
||||
cmdtype cmd;
|
||||
{
|
||||
cmdtype movecmd; /* movement command for y, d, c */
|
||||
char cmdch;
|
||||
int oldc; /* old count */
|
||||
int endp; /* end position before change */
|
||||
extern bool s_wrapped;
|
||||
|
||||
resetX(); /* un-derange the cursor */
|
||||
oldc = newc = -1;
|
||||
endY = yp;
|
||||
newend = disp = curr;
|
||||
ok = TRUE; /* so far everything is working */
|
||||
cmdch = ch;
|
||||
if (cmd != UNDO_C && cmd != YANK_C) {
|
||||
if (macro<0)
|
||||
zerostack(&undo);
|
||||
if (redoing != TRUE) {
|
||||
rcp = rcb; /* point at start of redo buffer */
|
||||
if (count > 1) { /* put in a count? */
|
||||
numtoa(rcb,count);
|
||||
rcp += strlen(rcb);
|
||||
}
|
||||
*rcp++ = cmdch; /* the command char goes in... */
|
||||
xerox = TRUE; /* hoist the magical flags */
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd <= YANK_C) {
|
||||
readchar();
|
||||
if ( isdigit(ch) && ch != '0' ) {
|
||||
oldc = count;
|
||||
count = 0;
|
||||
gcount(); /* get a new count */
|
||||
if (cmd == ADJUST_C) /* special for >>,<< wierdness */
|
||||
swap(&count, &oldc); /* reverse sw & count */
|
||||
else
|
||||
count = count*max(oldc,1); /* combine them */
|
||||
}
|
||||
if (ch == cmdch) { /* diddle lines */
|
||||
yank.lines = TRUE;
|
||||
endp = nextline(TRUE, curr, count);
|
||||
curr = bseekeol(curr);
|
||||
disp = curr;
|
||||
}
|
||||
else { /* diddle 'things' */
|
||||
yank.lines = FALSE;
|
||||
movecmd = movemap[(unsigned int)ch];
|
||||
|
||||
if ( (ok = (findCP(curr,&endp,movecmd) == LEGALMOVE)) ) {
|
||||
if (curr > endp) {
|
||||
swap(&curr,&endp);
|
||||
ok = (cmd != CHANGE_C);
|
||||
}
|
||||
if (adjcurr[(unsigned int)movecmd])
|
||||
curr++;
|
||||
if (adjendp[(unsigned int)movecmd])
|
||||
endp++;
|
||||
}
|
||||
if (!ok) {
|
||||
if (ch != ESC)
|
||||
error();
|
||||
goto killredo;
|
||||
}
|
||||
}
|
||||
|
||||
endY = setY(endp);
|
||||
newend = curr;
|
||||
disp = curr;
|
||||
switch (cmd) {
|
||||
case EXEC_C:
|
||||
ok = execute(curr, endp);
|
||||
break;
|
||||
case DELETE_C:
|
||||
ok = deletion(curr, endp);
|
||||
break;
|
||||
case ADJUST_C:
|
||||
adjuster((cmdch == '<'), endp-1, oldc);
|
||||
break;
|
||||
case CHANGE_C:
|
||||
if (endp <= pend+1) {
|
||||
mvcur(setY(endp-1), setX(endp-1));
|
||||
printch('$');
|
||||
mvcur(yp, xp);
|
||||
}
|
||||
if (deletion(curr, endp))
|
||||
ok = ((newend = insertion(1, 0, &disp, &endY, TRUE)) >= 0);
|
||||
else
|
||||
ok = FALSE;
|
||||
break;
|
||||
case YANK_C:
|
||||
if (!doyank(curr, endp))
|
||||
error();
|
||||
return; /* xerox will not be true, nor will redoing */
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
endp = curr;
|
||||
endY = yp;
|
||||
|
||||
switch (cmd) {
|
||||
case I_AT_NONWHITE:
|
||||
case A_AT_END:
|
||||
case APPEND_C:
|
||||
case INSERT_C: /* variations on insert */
|
||||
if (cmd != INSERT_C) {
|
||||
if (cmd == APPEND_C)
|
||||
curr = min(curr+1, lend);
|
||||
else if (cmd == A_AT_END)
|
||||
curr = lend;
|
||||
else /* if (cmd == I_AT_NONWHITE) */
|
||||
curr = skipws(lstart);
|
||||
xp = setX(curr);
|
||||
mvcur(yp,xp);
|
||||
}
|
||||
newend = insertion(count, 0, &disp, &endY, TRUE);
|
||||
ok = (newend >= 0);
|
||||
break;
|
||||
case OPEN_C:
|
||||
case OPENUP_C:
|
||||
newend = insertion(1,setstep[ (cmd==OPENUP_C)&1 ],
|
||||
&disp,&endY,TRUE)-1;
|
||||
ok = (newend >= 0);
|
||||
break;
|
||||
case REPLACE_C:
|
||||
case TWIDDLE_C:
|
||||
if (cmd == REPLACE_C) {
|
||||
if ((cmdch = readchar()) == ESC)
|
||||
goto killredo;
|
||||
}
|
||||
if (findCP(curr, &endp, GO_RIGHT) == LEGALMOVE)
|
||||
squiggle(endp-1, cmdch, (cmd==REPLACE_C));
|
||||
break;
|
||||
case PUT_BEFORE:
|
||||
case PUT_AFTER:
|
||||
ok = put(cmd==PUT_AFTER);
|
||||
break;
|
||||
case BIG_REPL_C:
|
||||
bigreplace();
|
||||
break;
|
||||
case RESUBST_C:
|
||||
ok = FALSE;
|
||||
if (dst[0] != 0) {
|
||||
newend = chop(curr, &lend, TRUE, &ok);
|
||||
if (newend >= 0) {
|
||||
endY = setY(newend+strlen(dst));
|
||||
ok = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JOIN_C:
|
||||
join(count); /* join lines */
|
||||
break;
|
||||
case UNDO_C: /* undo last modification */
|
||||
ok = fixcore(&newend) >= 0;
|
||||
disp = newend;
|
||||
endY = MAGICNUMBER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
setpos((newc<0)?newend:newc);
|
||||
setend();
|
||||
if (curr < ptop || curr > pend) {
|
||||
yp = settop(12);
|
||||
redisplay(TRUE);
|
||||
}
|
||||
else {
|
||||
yp = setY(curr);
|
||||
if (endY != setY(newend)) /* shuffled lines */
|
||||
refresh(setY(disp), setX(disp), disp, pend, TRUE);
|
||||
else /* refresh to end position */
|
||||
refresh(setY(disp), setX(disp), disp, newend, FALSE);
|
||||
}
|
||||
if (curr >= bufmax && bufmax > 0) { /* adjust off end of buffer */
|
||||
setpos(bufmax-1);
|
||||
yp = setY(curr);
|
||||
}
|
||||
if (s_wrapped) {
|
||||
prompt(FALSE, "search wrapped around end of buffer");
|
||||
s_wrapped = 0;
|
||||
}
|
||||
else
|
||||
clrprompt();
|
||||
modified = TRUE;
|
||||
}
|
||||
else {
|
||||
error();
|
||||
killredo:
|
||||
rcb[0] = 0;
|
||||
}
|
||||
mvcur(yp, xp);
|
||||
if (xerox)
|
||||
*rcp = 0; /* terminate the redo */
|
||||
redoing = FALSE;
|
||||
xerox = FALSE;
|
||||
core[bufmax] = EOL;
|
||||
}
|
||||
|
||||
/* Initialize && execute a macro */
|
||||
|
||||
VOID PROC
|
||||
exmacro()
|
||||
{
|
||||
int mp;
|
||||
|
||||
mp = lookup(ch);
|
||||
if (mp > 0) {
|
||||
if (macro<0)
|
||||
zerostack(&undo);
|
||||
insertmacro(mbuffer[mp].m_text, count);
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
/* redraw the screen w.r.t. the cursor */
|
||||
|
||||
VOID PROC
|
||||
zdraw(code)
|
||||
unsigned char code;
|
||||
{
|
||||
int nl = ERR,
|
||||
np = (count>0)?to_index(count):curr;
|
||||
|
||||
if (movemap[code] == CR_FWD)
|
||||
nl = 0;
|
||||
else if (movemap[code] == CR_BACK)
|
||||
nl = LINES-1;
|
||||
else if (code == '.')
|
||||
nl = LINES / 2;
|
||||
if (nl >= 0) {
|
||||
curr = np;
|
||||
yp = settop(nl);
|
||||
redisplay(TRUE);
|
||||
mvcur(yp,xp);
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
/* start up a built-in macro */
|
||||
|
||||
VOID PROC
|
||||
macrocommand()
|
||||
{
|
||||
if (count > 1)
|
||||
numtoa(gcb,count);
|
||||
else
|
||||
gcb[0] = 0;
|
||||
switch (ch) { /* which macro? */
|
||||
case 'x': /* x out characters */
|
||||
strcat(gcb,"dl"); break;
|
||||
case 'X': /* ... backwards */
|
||||
strcat(gcb,"dh"); break;
|
||||
case 's': /* substitute over chars */
|
||||
strcat(gcb,"cl"); break;
|
||||
case 'D': /* delete to end of line */
|
||||
strcat(gcb,"d$"); break;
|
||||
case 'C': /* change ... */
|
||||
strcat(gcb,"c$"); break;
|
||||
case 'Y': /* yank ... */
|
||||
strcat(gcb,"y$"); break;
|
||||
case '': /* scroll up one page */
|
||||
strcpy(gcb,"22"); break;
|
||||
case '': /* ... down one page */
|
||||
strcpy(gcb,"22"); break;
|
||||
case '': /* scroll up one line */
|
||||
strcpy(gcb,"1"); break;
|
||||
case '': /* ... down one line */
|
||||
strcpy(gcb,"1"); break;
|
||||
default:
|
||||
error();
|
||||
return;
|
||||
break;
|
||||
}
|
||||
if (macro<0)
|
||||
zerostack(&undo);
|
||||
insertmacro(gcb, 1);
|
||||
}
|
||||
|
||||
/* scroll the window up || down */
|
||||
|
||||
VOID PROC
|
||||
scroll(down)
|
||||
bool down;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (count <= 0)
|
||||
count = dofscroll;
|
||||
strput(CURoff);
|
||||
if (down) {
|
||||
curr = min(bufmax-1, nextline(TRUE, curr, count));
|
||||
i = min(bufmax-1, nextline(TRUE, pend, count));
|
||||
if (i > pend)
|
||||
scrollforward(i);
|
||||
}
|
||||
else {
|
||||
curr = bseekeol(max(0,nextline(FALSE, curr, count)));
|
||||
i = bseekeol(max(0,nextline(FALSE, ptop, count)));
|
||||
if (i < ptop) {
|
||||
if (canUPSCROLL)
|
||||
scrollback(i);
|
||||
else {
|
||||
ptop = i;
|
||||
setend();
|
||||
redisplay(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
strput(CURon);
|
||||
setpos(skipws(curr)); /* initialize new position - first nonwhite */
|
||||
yp = setY(curr);
|
||||
mvcur(yp, xp); /* go there */
|
||||
}
|
||||
|
||||
exec_type PROC
|
||||
editcore()
|
||||
{
|
||||
cmdtype cmd;
|
||||
extern bool s_wrapped;
|
||||
|
||||
/* rcb[0] = 0; rcp = rcb; */
|
||||
|
||||
if (diddled) {
|
||||
setpos(skipws(curr)); /* set cursor x position.. */
|
||||
yp = settop(LINES / 2); /* Y position */
|
||||
}
|
||||
if (diddled || zotscreen) /* redisplay? */
|
||||
redisplay(FALSE);
|
||||
mvcur(yp, xp); /* and move the cursor */
|
||||
|
||||
for (;;) {
|
||||
s_wrapped = 0;
|
||||
ch = readchar(); /* get a char */
|
||||
count = 0;
|
||||
if (isdigit(ch) && ch != '0')
|
||||
gcount(); /* ... a possible count */
|
||||
switch (cmd = movemap[(unsigned int)ch]) {
|
||||
case FILE_C:
|
||||
wr_stat(); /* write file stats */
|
||||
mvcur(yp, xp);
|
||||
break;
|
||||
|
||||
case WINDOW_UP:
|
||||
case WINDOW_DOWN:
|
||||
scroll(cmd==WINDOW_UP); /* scroll the window */
|
||||
break;
|
||||
|
||||
case REDRAW_C: /* redraw the window */
|
||||
redisplay(TRUE);
|
||||
mvcur(yp, xp);
|
||||
break;
|
||||
|
||||
case MARKER_C: /* set a marker */
|
||||
ch = tolower(readchar());
|
||||
if (ch >= 'a' && ch <= 'z')
|
||||
contexts[ch-'`'] = curr;
|
||||
else if (ch != ESC)
|
||||
error();
|
||||
break;
|
||||
|
||||
case REDO_C:
|
||||
if (rcb[0] != 0) {
|
||||
zerostack(&undo);
|
||||
insertmacro(rcb, 1);
|
||||
redoing = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case REWINDOW:
|
||||
zdraw(readchar()); /* shift the window */
|
||||
break;
|
||||
|
||||
case DEBUG_C: /* debugging stuff -- unused */
|
||||
break;
|
||||
|
||||
case ZZ_C: /* shortcut for :xit */
|
||||
ch = readchar();
|
||||
if (ch == 'Z')
|
||||
insertmacro(":x\r", 1);
|
||||
else if (ch != ESC)
|
||||
error();
|
||||
break;
|
||||
|
||||
case EDIT_C: /* drop into line mode */
|
||||
return E_EDIT;
|
||||
|
||||
case COLIN_C: /* do one exec mode command */
|
||||
return E_VISUAL;
|
||||
|
||||
case HARDMACRO:
|
||||
macrocommand(); /* 'hard-wired' macros */
|
||||
break;
|
||||
|
||||
case SOFTMACRO:
|
||||
exmacro(); /* run a macro */
|
||||
break;
|
||||
|
||||
case INSMACRO: /* macro for insert mode */
|
||||
case BAD_COMMAND:
|
||||
error();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (cmd < DELETE_C)
|
||||
movearound(cmd);
|
||||
else /*if (cmd < HARDMACRO)*/
|
||||
docommand(cmd);
|
||||
break;
|
||||
}
|
||||
lastexec = 0;
|
||||
}
|
||||
/* never exits here */
|
||||
}
|
||||
1114
src/cmd/levee/exec.c
Normal file
1114
src/cmd/levee/exec.c
Normal file
File diff suppressed because it is too large
Load Diff
237
src/cmd/levee/extern.h
Normal file
237
src/cmd/levee/extern.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#ifndef GLOBALS_D
|
||||
#define GLOBALS_D
|
||||
extern
|
||||
char lastchar, /* Last character read via peekc */
|
||||
ch; /* Global command char */
|
||||
extern
|
||||
exec_type mode; /* editor init state */
|
||||
extern
|
||||
int lastexec; /* last exec mode command */
|
||||
|
||||
extern
|
||||
int contexts['z'-'`'+1]; /* Labels */
|
||||
/* C O N S T A N T S */
|
||||
extern
|
||||
bool adjcurr[PARA_BACK+1],
|
||||
adjendp[PARA_BACK+1];
|
||||
/* A R G U M E N T S */
|
||||
extern
|
||||
char startcmd[]; /* initial command after read */
|
||||
extern
|
||||
char **argv; /* Arguments */
|
||||
extern
|
||||
int argc, /* # arguments */
|
||||
pc; /* Index into arguments */
|
||||
/* M A C R O S T U F F */
|
||||
extern
|
||||
struct macrecord mbuffer[];
|
||||
extern
|
||||
struct tmacro mcr[]; /* A place for executing macros */
|
||||
/* S E A R C H S T U F F */
|
||||
extern
|
||||
char dst[], /* last replacement pattern */
|
||||
lastpatt[], /* last search pattern */
|
||||
pattern[];
|
||||
extern
|
||||
int RE_start[9], /* start of substitute argument */
|
||||
RE_size [9], /* size of substitute argument */
|
||||
lastp; /* last character matched in search */
|
||||
extern
|
||||
struct undostack undo; /* To undo a command */
|
||||
/* R A N D O M S T R I N G S */
|
||||
|
||||
extern
|
||||
char instring[], /* Latest input */
|
||||
filenm[], /* Filename */
|
||||
altnm[], /* Alternate filename */
|
||||
gcb[]; /* Command buffer for mutations of insert */
|
||||
|
||||
extern
|
||||
char undobuf[],
|
||||
undotmp[],
|
||||
yankbuf[];
|
||||
extern
|
||||
int uread, /* reading from the undo stack */
|
||||
uwrite; /* writing to the undo stack */
|
||||
/* B U F F E R S */
|
||||
extern
|
||||
char rcb[], *rcp, /* last modification command */
|
||||
core[]; /* data space */
|
||||
|
||||
extern
|
||||
struct ybuf yank; /* last deleted/yanked text */
|
||||
/* STATIC INITIALIZATIONS: */
|
||||
|
||||
/* ttydef stuff */
|
||||
#if OS_ATARI | USE_TERMCAP
|
||||
extern int LINES, COLS;
|
||||
#endif
|
||||
|
||||
#if USE_TERMCAP
|
||||
extern bool CA, canUPSCROLL;
|
||||
extern char FkL,
|
||||
CurRT,
|
||||
CurLT,
|
||||
CurDN,
|
||||
CurUP;
|
||||
#endif /*USE_TERMCAP*/
|
||||
|
||||
extern char *TERMNAME,
|
||||
*HO,
|
||||
*UP,
|
||||
*CE,
|
||||
*CL,
|
||||
*OL,
|
||||
*BELL,
|
||||
*CM,
|
||||
*UpS,
|
||||
*CURoff,
|
||||
*CURon;
|
||||
|
||||
extern
|
||||
char Erasechar,
|
||||
eraseline;
|
||||
|
||||
extern
|
||||
char codeversion[], /* Editor version */
|
||||
fismod[], /* File is modified message */
|
||||
fisro[]; /* permission denied message */
|
||||
|
||||
extern
|
||||
char *excmds[],
|
||||
wordset[],
|
||||
spaces[];
|
||||
extern
|
||||
struct variable vars[];
|
||||
extern
|
||||
int autowrite,
|
||||
autocopy,
|
||||
overwrite,
|
||||
beautify,
|
||||
autoindent,
|
||||
dofscroll,
|
||||
shiftwidth,
|
||||
tabsize,
|
||||
list,
|
||||
wrapscan,
|
||||
bell,
|
||||
magic;
|
||||
/*extern
|
||||
char *suffix; */
|
||||
/* For movement routines */
|
||||
extern
|
||||
int setstep[];
|
||||
/* Where the last diddling left us */
|
||||
extern
|
||||
struct coord curpos;
|
||||
|
||||
/* initialize the buffer */
|
||||
extern
|
||||
int curr, /* Global cursor pos */
|
||||
lstart, lend, /* Start & end of current line */
|
||||
count, /* Latest count */
|
||||
xp, yp, /* Cursor window position */
|
||||
bufmax, /* End of file here */
|
||||
ptop, pend; /* Top & bottom of CRT window */
|
||||
extern
|
||||
bool modified, /* File has been modified */
|
||||
readonly, /* is this file readonly? */
|
||||
needchar, /* Peekc flag */
|
||||
deranged, /* Up-arrow || down-arrow left xpos in Oz. */
|
||||
indirect, /* Reading from an indirect file?? */
|
||||
redoing, /* doing a redo? */
|
||||
xerox, /* making a redo buffer? */
|
||||
newfile, /* Editing a new file? */
|
||||
newline, /* Last insert/delete included a EOL */
|
||||
lineonly, /* Dumb terminal? */
|
||||
zotscreen, /* do more after command in execmode */
|
||||
diddled; /* force redraw when I enter editcore */
|
||||
|
||||
extern
|
||||
int macro; /* Index into MCR macro execution stack */
|
||||
extern
|
||||
char lsearch;
|
||||
/* movement, command codes */
|
||||
extern
|
||||
cmdtype movemap[];
|
||||
#endif /*GLOBALS_D*/
|
||||
#ifndef EXTERN_D
|
||||
#define EXTERN_D
|
||||
#define wc(ch) (scan(65,'=',(ch),wordset)<65)
|
||||
|
||||
#if HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_MEMSET
|
||||
#define fillchar(p,l,c) memset((p),(c),(l))
|
||||
#elif HAVE_BLKFILL
|
||||
#define fillchar(p,l,c) blkfill((p),(c),(l))
|
||||
#endif
|
||||
#if HAVE_STRCHR
|
||||
#define index(s,c) strchr((s),(c))
|
||||
#endif
|
||||
|
||||
extern findstates PROC findCP();
|
||||
extern exec_type PROC editcore();
|
||||
|
||||
extern char PROC line(), peekc(), readchar();
|
||||
extern char PROC *findparse(),*makepat();
|
||||
|
||||
extern bool PROC getlin();
|
||||
extern bool PROC putfile();
|
||||
extern bool PROC doyank(), deletion(), putback();
|
||||
extern bool PROC pushb(),pushi(),pushmem(),uputcmd(), delete_to_undo();
|
||||
extern bool PROC ok_to_scroll(), move_to_undo();
|
||||
|
||||
extern int PROC min(), max(), fseekeol(), bseekeol(), settop();
|
||||
extern int PROC scan(), findDLE(), setY(), skipws(), nextline(), setX();
|
||||
extern int PROC insertion(), chop(), fixcore(), lookup(), to_index();
|
||||
extern int PROC doaddwork(), addfile(), expandargs(), to_line();
|
||||
extern int PROC findfwd(), findback(), getcontext(), getKey();
|
||||
extern int PROC cclass();
|
||||
extern int PROC insertfile();
|
||||
|
||||
extern VOID PROC strput(), numtoa(), clrprompt(), setend(), error();
|
||||
extern VOID PROC insert_to_undo(), resetX(), zerostack(), swap();
|
||||
extern VOID PROC mvcur(), printch(), prints(), writeline(), refresh();
|
||||
extern VOID PROC redisplay(), scrollback(), scrollforward(), prompt();
|
||||
extern VOID PROC setpos(), resetX(), insertmacro(), wr_stat();
|
||||
extern VOID PROC movearound(), printi(), println(), killargs();
|
||||
extern VOID PROC exec(), initcon(), fixcon(), version(), setcmd();
|
||||
extern VOID PROC toedit(), inputf(), fixmarkers(), errmsg();
|
||||
|
||||
#ifndef moveleft
|
||||
extern VOID PROC moveleft();
|
||||
#endif
|
||||
#ifndef moveright
|
||||
extern VOID PROC moveright();
|
||||
#endif
|
||||
#ifndef fillchar
|
||||
extern VOID PROC fillchar();
|
||||
#endif
|
||||
|
||||
#if USE_TERMCAP
|
||||
extern void tc_init();
|
||||
#endif
|
||||
|
||||
#endif /*EXTERN_D*/
|
||||
514
src/cmd/levee/find.c
Normal file
514
src/cmd/levee/find.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
#include "grep.h"
|
||||
#include <ctype.h>
|
||||
|
||||
int PROC amatch();
|
||||
int PROC locate();
|
||||
VOID PROC patsize();
|
||||
|
||||
static int arg; /* arguments inside of a RE */
|
||||
|
||||
int PROC
|
||||
REmatch(pattern, start, end)
|
||||
char *pattern;
|
||||
int start,end;
|
||||
{
|
||||
char *endp = &core[end];
|
||||
|
||||
if (!*pattern)
|
||||
return -1;
|
||||
arg = 0;
|
||||
while (start <= end && !amatch(pattern, &core[start], endp))
|
||||
start++;
|
||||
return start;
|
||||
}
|
||||
|
||||
int PROC
|
||||
omatch(pattern, cp, endp)
|
||||
char *pattern, **cp, *endp;
|
||||
{
|
||||
register int flag;
|
||||
extern int ignorecase;
|
||||
|
||||
switch (*pattern) {
|
||||
case LEND:
|
||||
return (**cp == EOL);
|
||||
case LSTART:
|
||||
return (*cp == core) || (*(*cp-1) == EOL);
|
||||
case TOKENB:
|
||||
return (*cp == core) || !isalnum(*(*cp-1));
|
||||
case TOKENE:
|
||||
return !isalnum(**cp);
|
||||
case LITCHAR:
|
||||
if (ignorecase)
|
||||
flag = (toupper(**cp) == toupper(*(pattern+1)));
|
||||
else
|
||||
flag = (**cp == *(pattern+1));
|
||||
break;
|
||||
case ANY:
|
||||
flag = (**cp != EOL);
|
||||
break;
|
||||
case CCL:
|
||||
flag = locate(pattern,*cp);
|
||||
break;
|
||||
case NCCL:
|
||||
flag = !locate(pattern,*cp);
|
||||
break;
|
||||
case ARGSTART:
|
||||
RE_start[arg] = (*cp)-core;
|
||||
return TRUE;
|
||||
case ARGEND:
|
||||
RE_size[arg] = ((*cp)-core) - RE_start[arg];
|
||||
++arg;
|
||||
return TRUE;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (*cp <= endp && flag) {
|
||||
(*cp)++;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int PROC
|
||||
amatch(pattern,start,endp)
|
||||
char *pattern, *endp, *start;
|
||||
{
|
||||
int sarg = arg; /* save old arg match count for errors */
|
||||
|
||||
while (*pattern) {
|
||||
if (*pattern == CLOSURE) {
|
||||
/* Find the longest closure possible and work backwards trying
|
||||
* to match the rest of the pattern.
|
||||
*/
|
||||
char *oldstart = start;
|
||||
|
||||
++pattern; /* skip over the closure token */
|
||||
while (start <= endp && omatch(pattern,&start,endp))
|
||||
;
|
||||
/* start points at the character that failed the search.
|
||||
* Try to match the rest of the pattern against it, working
|
||||
* back down the line if failure
|
||||
*/
|
||||
patsize(&pattern);
|
||||
while (start >= oldstart)
|
||||
if (amatch(pattern,start--,endp))
|
||||
return TRUE;
|
||||
arg = sarg;
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
if (!omatch(pattern,&start,endp)) {
|
||||
arg = sarg;
|
||||
return FALSE;
|
||||
}
|
||||
patsize(&pattern);
|
||||
}
|
||||
}
|
||||
lastp = start-core;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* increment pattern by the size of the token being scanned
|
||||
*/
|
||||
VOID PROC
|
||||
patsize(pattern)
|
||||
register char **pattern;
|
||||
{
|
||||
register int count;
|
||||
|
||||
switch (**pattern) {
|
||||
case LITCHAR:
|
||||
*pattern += 2;
|
||||
break;
|
||||
case CCL:
|
||||
case NCCL:
|
||||
count = *(++*pattern) & 0xff;
|
||||
*pattern += 1+count;
|
||||
break;
|
||||
default:
|
||||
(*pattern)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int PROC
|
||||
locate(pattern,linep)
|
||||
/* locate: find a character in a closure */
|
||||
char *pattern;
|
||||
register char *linep;
|
||||
{
|
||||
register char *p = 1+pattern;
|
||||
register int count;
|
||||
|
||||
if ((count = (*p++)&0xff) == 0)
|
||||
return FALSE;
|
||||
while (count--)
|
||||
if (*p++ == *linep)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
char *p;
|
||||
|
||||
VOID PROC
|
||||
concatch(c)
|
||||
/* add a character to the pattern */
|
||||
char c;
|
||||
{
|
||||
if (p < &pattern[MAXPAT-1])
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
char PROC
|
||||
esc(s)
|
||||
char **s;
|
||||
{
|
||||
if (**s != ESCAPE || *(1+*s) == 0)
|
||||
return **s;
|
||||
++(*s);
|
||||
switch (**s) {
|
||||
case 't': return TAB;
|
||||
case 'n': return EOL;
|
||||
}
|
||||
return **s;
|
||||
}
|
||||
|
||||
char * PROC
|
||||
dodash(src)
|
||||
/* parse the innards of a [] */
|
||||
char *src;
|
||||
{
|
||||
int k;
|
||||
char *start = src;
|
||||
char cs[128];
|
||||
|
||||
fillchar(cs,sizeof(cs),FALSE);
|
||||
while (*src && *src != CCLEND) {
|
||||
if (*src == DASH && src>start && src[1] != CCLEND && src[-1]<src[1]) {
|
||||
for ( k = src[-1]; k <= src[1]; k++)
|
||||
cs[k] = TRUE;
|
||||
src++;
|
||||
}
|
||||
else
|
||||
cs[(unsigned int)esc(&src)] = TRUE;
|
||||
src++;
|
||||
}
|
||||
for (k=0; k < sizeof(cs); k++)
|
||||
if (cs[k])
|
||||
concatch((char)k);
|
||||
return src;
|
||||
}
|
||||
|
||||
char * PROC
|
||||
badccl(src)
|
||||
/* a [] was encountered. is it a CCL (match one of the included
|
||||
* characters); or is it a NCCL (match all but the included characters)?
|
||||
*/
|
||||
char *src;
|
||||
{
|
||||
char *jstart;
|
||||
|
||||
if (*src == NEGATE) {
|
||||
concatch(NCCL);
|
||||
++src;
|
||||
}
|
||||
else
|
||||
concatch(CCL);
|
||||
jstart = p;
|
||||
concatch(0); /* this will be the length of the pattern */
|
||||
src = dodash(src);
|
||||
*jstart = (p-jstart)-1;
|
||||
return src;
|
||||
}
|
||||
|
||||
/* patterns that cannot be closed */
|
||||
char badclose[] = { LSTART, LEND, CLOSURE, 0 };
|
||||
|
||||
char * PROC
|
||||
makepat(string,delim)
|
||||
char *string, delim;
|
||||
/* make up the pattern string for find -- ripped from 'Software Tools' */
|
||||
{
|
||||
char *cp = 0, *oldcp;
|
||||
char *start = string;
|
||||
int inarg = FALSE;
|
||||
|
||||
for(arg=0;arg<9;++arg)
|
||||
RE_start[arg] = RE_size[arg] = (-1);
|
||||
arg = 0;
|
||||
p = pattern;
|
||||
|
||||
while ((*string != delim) && (*string != 0)) {
|
||||
oldcp = cp;
|
||||
cp = p;
|
||||
|
||||
if (!magic) /* kludge for nonmagical patterns */
|
||||
goto normal;
|
||||
if (*string == ANY)
|
||||
concatch(ANY);
|
||||
else if ((*string == LSTART) && (string == start))
|
||||
concatch(LSTART);
|
||||
else if ((*string == LEND) && (string[1] == delim || string[1] == 0))
|
||||
concatch(LEND);
|
||||
else if (*string == CCL)
|
||||
string = badccl(1+string);
|
||||
else if ((*string == CLOSURE) && (p > pattern)) {
|
||||
cp = oldcp;
|
||||
if (strchr(badclose, *cp) || p >= &pattern[MAXPAT-1])
|
||||
return NULL;
|
||||
moveright(cp,1+cp,(int)(p-cp));
|
||||
*cp = CLOSURE;
|
||||
p++;
|
||||
}
|
||||
else if (*string == ESCAPE) {
|
||||
if (string[1] == ARGSTART || string[1] == ARGEND) {
|
||||
if (string[1] == ARGEND)
|
||||
if (!inarg)
|
||||
goto normal;
|
||||
if (string[1] == ARGSTART) {
|
||||
if (inarg)
|
||||
goto normal;
|
||||
if (++arg > 9)
|
||||
return NULL;
|
||||
}
|
||||
inarg = !inarg;
|
||||
}
|
||||
else if (string[1] != TOKENB && string[1] != TOKENE)
|
||||
goto normal;
|
||||
++string;
|
||||
concatch(*string);
|
||||
}
|
||||
else {
|
||||
normal:concatch(LITCHAR);
|
||||
concatch(esc(&string));
|
||||
}
|
||||
if (*string)
|
||||
string++;
|
||||
}
|
||||
if (inarg)
|
||||
concatch(ARGEND);
|
||||
if (p > pattern) { /* new pattern was created */
|
||||
strncpy(lastpatt,start,(int)(string-start));
|
||||
lastpatt[string-start] = 0;
|
||||
concatch(0);
|
||||
if (p-pattern >= MAXPAT)
|
||||
return NULL;
|
||||
}
|
||||
return (*string == delim)?(string+1):(string);
|
||||
}
|
||||
|
||||
int PROC
|
||||
findfwd(pattern,start,endp)
|
||||
/* look for a regular expression forward */
|
||||
char *pattern;
|
||||
int start, endp;
|
||||
{
|
||||
int ep;
|
||||
|
||||
while (start < endp) {
|
||||
ep = fseekeol(start);
|
||||
if ((start = REmatch(pattern, start, ep)) <= ep)
|
||||
return start;
|
||||
}
|
||||
return ERR;
|
||||
}
|
||||
|
||||
int PROC
|
||||
findback(pattern,start,endp)
|
||||
/* look for a regular expression backwards */
|
||||
char *pattern;
|
||||
int start, endp;
|
||||
{
|
||||
int ep,i;
|
||||
|
||||
while (start > endp) {
|
||||
ep = bseekeol(start);
|
||||
if ((i = REmatch(pattern, ep, start)) <= start)
|
||||
return i;
|
||||
start = ep-1;
|
||||
}
|
||||
return ERR;
|
||||
}
|
||||
|
||||
bool s_wrapped = 0;
|
||||
|
||||
char * PROC
|
||||
search(pat, start)
|
||||
/* get a token for find & find it in the buffer
|
||||
*/
|
||||
char *pat;
|
||||
int *start;
|
||||
{
|
||||
bool forwd;
|
||||
int pos;
|
||||
char *p;
|
||||
|
||||
forwd = ((lsearch = *pat) == '/');
|
||||
if ((p=makepat(pat+1,*pat)) == NULL) {
|
||||
*start = ERR;
|
||||
return pat;
|
||||
}
|
||||
do {
|
||||
if (forwd) {
|
||||
pos = findfwd(pattern, (*start)+1, bufmax-1);
|
||||
if ((pos == ERR) && wrapscan) {
|
||||
s_wrapped = 1;
|
||||
pos = findfwd(pattern, 0, (*start)-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pos = findback(pattern, (*start)-1, 0);
|
||||
if ((pos == ERR) && wrapscan) {
|
||||
s_wrapped = 1;
|
||||
pos = findback(pattern, bufmax-1, (*start)+1);
|
||||
}
|
||||
}
|
||||
*start = pos;
|
||||
} while (--count > 0 && *start != ERR);
|
||||
return p;
|
||||
}
|
||||
|
||||
char * PROC
|
||||
findparse(src,idx,start) /* driver for ?, /, && : lineranges */
|
||||
char *src;
|
||||
int *idx,start;
|
||||
{
|
||||
int addr = start;
|
||||
char c;
|
||||
|
||||
s_wrapped = 0;
|
||||
|
||||
switch (*src) {
|
||||
case '/':
|
||||
case '?':
|
||||
/* get a token for find & find it in the buffer */
|
||||
src = search(src,&addr);
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
/* fabricate a count */
|
||||
count = 0;
|
||||
while (*src >= '0' && *src <= '9')
|
||||
count = (count*10) + *(src++) - '0';
|
||||
|
||||
addr = to_index(count);
|
||||
break;
|
||||
case '$':
|
||||
addr = bufmax-1;
|
||||
src++;
|
||||
break;
|
||||
case '.' :
|
||||
src++;
|
||||
break;
|
||||
case '`':
|
||||
case '\'':
|
||||
addr = getcontext(*(src+1), (*src == '\''));
|
||||
src += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
while (addr>=0 && (*src =='+' || *src == '-')) {
|
||||
c = *(src++);
|
||||
/* skip delimiter */
|
||||
if (*src == '/' || *src == '?') {
|
||||
count = 1;
|
||||
if ((src = search(src,&addr)) == NULL)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (*src >= '0' && *src <= '9') {
|
||||
/* fabricate a count */
|
||||
count = 0;
|
||||
while (*src >= '0' && *src <= '9')
|
||||
count = (count*10) + *(src++) - '0';
|
||||
}
|
||||
else
|
||||
count = -1; /* for naked + & - */
|
||||
if (count == 0) /* +0 goes to beginning of line */
|
||||
addr = bseekeol(addr);
|
||||
else {
|
||||
addr = nextline((c=='+'), addr, count);
|
||||
if (c=='-' && addr > 0)
|
||||
addr = bseekeol(addr);
|
||||
}
|
||||
if (addr >= bufmax)
|
||||
addr = -1;
|
||||
}
|
||||
}
|
||||
*idx = addr;
|
||||
return(src);
|
||||
}
|
||||
|
||||
int PROC
|
||||
nextline(advance,dest,count)
|
||||
bool advance;
|
||||
int dest,count;
|
||||
{
|
||||
if (advance)
|
||||
do {
|
||||
dest = fseekeol(dest) + 1;
|
||||
count--;
|
||||
} while (count>0 && dest<bufmax);
|
||||
else
|
||||
do {
|
||||
dest = bseekeol(dest) - 1;
|
||||
count--;
|
||||
} while (count>0 && dest>=0);
|
||||
return(dest);
|
||||
}
|
||||
|
||||
int PROC
|
||||
fseekeol(origin)
|
||||
int origin;
|
||||
{
|
||||
return(origin + scan(bufmax-origin-1,'=',EOL,&core[origin]));
|
||||
}
|
||||
|
||||
int PROC
|
||||
bseekeol(origin)
|
||||
int origin;
|
||||
{
|
||||
return(origin + scan(-origin,'=',EOL,&core[origin-1]));
|
||||
}
|
||||
|
||||
/* get something from the context table */
|
||||
|
||||
int PROC
|
||||
getcontext(c,begline)
|
||||
char c;
|
||||
bool begline;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (c == '\'')
|
||||
c = '`';
|
||||
if (c >= '`' && c <= 'z')
|
||||
i = contexts[c-'`'];
|
||||
else
|
||||
i = -1;
|
||||
if (begline && i>=0)
|
||||
return(bseekeol(i));
|
||||
return(i);
|
||||
}
|
||||
122
src/cmd/levee/flexcall.c
Normal file
122
src/cmd/levee/flexcall.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* flexos interface for levee (Metaware C)
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#if OS_FLEXOS
|
||||
#include <flexos.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static int oldkmode;
|
||||
static int oldsmode;
|
||||
|
||||
int
|
||||
min(a,b)
|
||||
{
|
||||
return (a>b) ? b : a;
|
||||
}
|
||||
|
||||
int
|
||||
max(a,b)
|
||||
{
|
||||
return (a<b) ? b : a;
|
||||
}
|
||||
|
||||
strput(s)
|
||||
char *s;
|
||||
{
|
||||
s_write(0x01, 1L, s, (long)strlen(s), 0L);
|
||||
}
|
||||
|
||||
char *
|
||||
basename(s)
|
||||
char *s;
|
||||
{
|
||||
char *strrchr();
|
||||
char *p;
|
||||
|
||||
if ((p=strrchr(s,'/')) || (p=strrchr(s,'\\')) || (p = strrchr(s,':')))
|
||||
return 1+p;
|
||||
return s;
|
||||
}
|
||||
|
||||
getKey()
|
||||
{
|
||||
char c;
|
||||
|
||||
s_read(0x0101, 0L, &c, 1L, 0L);
|
||||
return c;
|
||||
}
|
||||
|
||||
initcon()
|
||||
{
|
||||
CONSOLE tty;
|
||||
|
||||
s_get(T_CON, 1L, &tty, SSIZE(tty));
|
||||
oldkmode = tty.con_kmode;
|
||||
oldsmode = tty.con_smode;
|
||||
tty.con_kmode = 0x0667;
|
||||
tty.con_smode = 0;
|
||||
s_set(T_CON, 1L, &tty, SSIZE(tty));
|
||||
}
|
||||
|
||||
fixcon()
|
||||
{
|
||||
CONSOLE tty;
|
||||
|
||||
s_get(T_CON, 1L, &tty, SSIZE(tty));
|
||||
tty.con_kmode = oldkmode;
|
||||
tty.con_smode = oldsmode;
|
||||
s_set(T_CON, 1L, &tty, SSIZE(tty));
|
||||
}
|
||||
|
||||
char *
|
||||
strdup(s)
|
||||
char *s;
|
||||
{
|
||||
char *malloc();
|
||||
char *p;
|
||||
|
||||
if (p=malloc(strlen(s)+1))
|
||||
strcpy(p, s);
|
||||
return p;
|
||||
}
|
||||
|
||||
getpid()
|
||||
{
|
||||
PROCESS myself;
|
||||
|
||||
s_get(T_PDEF, 0L, &myself, SSIZE(myself));
|
||||
|
||||
return myself.ps_pid;
|
||||
}
|
||||
|
||||
strlwr(s)
|
||||
char *s;
|
||||
{
|
||||
while (*s) {
|
||||
if (isupper(*s))
|
||||
*s += 32;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
70
src/cmd/levee/gemcall.c
Normal file
70
src/cmd/levee/gemcall.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* Gemdos (Atari ST) bindings for levee (Alcyon/Sozobon C)
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#if OS_ATARI
|
||||
#include <atari\osbind.h>
|
||||
|
||||
strput(s)
|
||||
register char *s;
|
||||
{
|
||||
write(1, s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
zwrite(s,len)
|
||||
char *s;
|
||||
{
|
||||
write(1, s, len);
|
||||
}
|
||||
|
||||
|
||||
min(a,b)
|
||||
register int a, b;
|
||||
{
|
||||
return (a<b)?a:b;
|
||||
}
|
||||
|
||||
|
||||
max(a,b)
|
||||
register int a, b;
|
||||
{
|
||||
return (a>b)?a:b;
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
getKey()
|
||||
/* get input from the keyboard. All odd keys (function keys, et al) that
|
||||
* do not produce a character have their scancode orred with $80 and returned.
|
||||
*/
|
||||
{
|
||||
unsigned c;
|
||||
long key;
|
||||
|
||||
c = (key = Crawcin()) & 0xff;
|
||||
if (!c)
|
||||
c = (((unsigned)(key>>16))|0x80) & 0xff;
|
||||
return c;
|
||||
} /* getKey */
|
||||
#endif /*OS_ATARI*/
|
||||
547
src/cmd/levee/globals.c
Normal file
547
src/cmd/levee/globals.c
Normal file
@@ -0,0 +1,547 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2008 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/* global declarations */
|
||||
|
||||
#include "levee.h"
|
||||
#define GLOBALS
|
||||
|
||||
char lastchar, /* Last character read via peekc */
|
||||
ch; /* Global command char */
|
||||
|
||||
exec_type mode; /* editor init state */
|
||||
int lastexec = 0; /* last exec command */
|
||||
|
||||
int contexts['z'-'`'+1]; /* Labels */
|
||||
|
||||
/* C O N S T A N T S */
|
||||
|
||||
bool adjcurr[PARA_BACK+1],
|
||||
adjendp[PARA_BACK+1];
|
||||
|
||||
/* A R G U M E N T S */
|
||||
char startcmd[80] = ""; /* initial command after read */
|
||||
char **argv; /* Arguments */
|
||||
int argc=0, /* # arguments */
|
||||
pc=0; /* Index into arguments */
|
||||
#if 0
|
||||
struct stat thisfile; /* status on current file, for writeout... */
|
||||
#endif
|
||||
|
||||
/* M A C R O S T U F F */
|
||||
struct macrecord mbuffer[MAXMACROS];
|
||||
struct tmacro mcr[NMACROS]; /* A place for executing macros */
|
||||
|
||||
/* S E A R C H S T U F F */
|
||||
char dst[80] = "", /* last replacement pattern */
|
||||
lastpatt[80] = "", /* last search pattern */
|
||||
pattern[MAXPAT] = ""; /* encoded last pattern */
|
||||
|
||||
int RE_start[9], /* start of substitution arguments */
|
||||
RE_size [9], /* size of substitution arguments */
|
||||
lastp; /* end of last pattern */
|
||||
|
||||
struct undostack undo; /* To undo a command */
|
||||
|
||||
|
||||
/* R A N D O M S T R I N G S */
|
||||
|
||||
char instring[200], /* Latest input */
|
||||
filenm[80] = "", /* Filename */
|
||||
altnm[80] = ""; /* Alternate filename */
|
||||
char gcb[16]; /* Command buffer for mutations of insert */
|
||||
|
||||
char undobuf[40];
|
||||
char undotmp[40];
|
||||
char yankbuf[40];
|
||||
|
||||
HANDLE uread, /* reading from the undo stack */
|
||||
uwrite; /* writing to the undo stack */
|
||||
|
||||
/* B U F F E R S */
|
||||
char rcb[256]; /* last modification command */
|
||||
char *rcp; /* this points at the end of the redo */
|
||||
char core[SIZE+1]; /* data space */
|
||||
|
||||
struct ybuf yank; /* last deleted/yanked text */
|
||||
|
||||
|
||||
/* STATIC INITIALIZATIONS: */
|
||||
|
||||
/* ttydef stuff */
|
||||
|
||||
#if OS_ATARI | USE_TERMCAP
|
||||
int LINES, COLS;
|
||||
#endif
|
||||
|
||||
#if TTY_ZTERM
|
||||
char *TERMNAME = "zterm",
|
||||
*HO = "\001", /* goto top of screen */
|
||||
*UP = "\002", /* move up 1 line? */
|
||||
*CE = "\003", /* clear to end of line */
|
||||
*CL = "\004", /* clearscreen */
|
||||
*OL = "\005", /* open current line down */
|
||||
*UpS = "\006", /* scroll up 1 line */
|
||||
*BELL= "\007", /* ring the bell */
|
||||
*CM = "yes", /* cursor movement exists */
|
||||
*CURoff,
|
||||
*CURon;
|
||||
#endif /*ZTERM*/
|
||||
|
||||
#if TTY_ANSI
|
||||
#if OS_DOS
|
||||
char *TERMNAME = "braindamaged ansi",
|
||||
#else
|
||||
char *TERMNAME = "hardwired ansi",
|
||||
#endif
|
||||
*HO = "\033[H",
|
||||
*UP = "\033[A",
|
||||
*CE = "\033[K",
|
||||
*CL = "\033[H\033[J",
|
||||
#if OS_DOS
|
||||
*OL = NULL,
|
||||
*UpS = NULL,
|
||||
#else
|
||||
*OL = "\033[L",
|
||||
*UpS = "\033[L",
|
||||
#endif
|
||||
*BELL= "\007",
|
||||
*CM = "\033[%d;%dH",
|
||||
*CURoff,
|
||||
*CURon;
|
||||
#endif /*TTY_ANSI*/
|
||||
|
||||
#if TTY_VT52
|
||||
#if OS_ATARI
|
||||
char *TERMNAME = "Atari ST",
|
||||
#else
|
||||
#if OS_FLEXOS
|
||||
char *TERMNAME = "Flexos console",
|
||||
#else
|
||||
char *TERMNAME = "hardwired vt52",
|
||||
#endif /*OS_FLEXOS*/
|
||||
#endif /*OS_ATARI*/
|
||||
*HO = "\033H",
|
||||
*UP = "\033A",
|
||||
*CE = "\033K",
|
||||
*CL = "\033E",
|
||||
*OL = "\033L",
|
||||
*BELL= "\007",
|
||||
*CM = "\033Y??",
|
||||
#if OS_FLEXOS
|
||||
*UpS = NULL, /* Reverse scrolling is painfully slow */
|
||||
#else
|
||||
*UpS = "\033I",
|
||||
#endif
|
||||
*CURoff= "\033f",
|
||||
*CURon = "\033e";
|
||||
#endif /*TTY_VT52*/
|
||||
|
||||
#if USE_TERMCAP
|
||||
bool CA, canUPSCROLL;
|
||||
char FkL, CurRT, CurLT, CurUP, CurDN;
|
||||
|
||||
char *TERMNAME, /* will be set in termcap handling */
|
||||
*HO,
|
||||
*UP,
|
||||
*CE,
|
||||
*CL,
|
||||
*OL,
|
||||
*BELL,
|
||||
*CM,
|
||||
*UpS,
|
||||
*CURoff,
|
||||
*CURon;
|
||||
#endif /*USE_TERMCAP*/
|
||||
|
||||
char Erasechar = ERASE, /* our erase character */
|
||||
eraseline = 'X'-'@'; /* and line-kill character */
|
||||
|
||||
char fismod[] = "File is modified", /* File is modified message */
|
||||
fisro[] = "File is readonly"; /* when you can't write the file */
|
||||
|
||||
char *excmds[] = {
|
||||
"print", /* lines to screen */
|
||||
"quit", /* quit editor */
|
||||
"read", /* add file to buffer */
|
||||
"edit", /* replace buffer with file */
|
||||
"write", /* write out file */
|
||||
"wq", /* write file and quit */
|
||||
"next", /* make new arglist or traverse this one */
|
||||
"substitute", /* pattern */
|
||||
"xit", /* write changes and quit */
|
||||
"file", /* show/set file name */
|
||||
"set", /* options */
|
||||
"rm", /* a file */
|
||||
"previous", /* back up in arglist */
|
||||
"delete", /* lines from buffer */
|
||||
"=", /* tell line number */
|
||||
"yank", /* lines from buffer */
|
||||
"put", /* back yanked lines */
|
||||
"visual", /* go to visual mode */
|
||||
"exec", /* go to exec mode */
|
||||
"insert", /* text below current line */
|
||||
"open", /* insert text above current line */
|
||||
"change", /* lines */
|
||||
"undo", /* last change */
|
||||
"!", /* shell escape */
|
||||
"map", /* keyboard macro */
|
||||
"unmap", /* keyboard macro */
|
||||
"source", /* read commands from file */
|
||||
"version", /* print version # */
|
||||
"args", /* print argument list */
|
||||
"rewind", /* rewind argument list */
|
||||
NULL
|
||||
};
|
||||
|
||||
char wordset[] = "0123456789$_#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
char spaces[] = { TAB,EOL,' ',0 };
|
||||
|
||||
int shiftwidth = 4,
|
||||
#if USE_TERMCAP | OS_ATARI
|
||||
dofscroll,
|
||||
#else
|
||||
dofscroll = LINES/2,
|
||||
#endif
|
||||
tabsize = 8;
|
||||
int autoindent = YES,
|
||||
autocopy = NO,
|
||||
autowrite = YES,
|
||||
wrapscan = YES,
|
||||
overwrite = YES,
|
||||
beautify = YES,
|
||||
list = NO,
|
||||
magic = YES,
|
||||
bell = YES,
|
||||
#if OS_ATARI
|
||||
mapslash,
|
||||
#endif
|
||||
ignorecase = NO;
|
||||
|
||||
struct variable vars[]={
|
||||
{"terminal", "", VSTR, V_CONST, (void*)&TERMNAME },
|
||||
{"shiftwidth","sw", VINT, 0, (void*)&shiftwidth },
|
||||
{"scroll", "", VINT, 0, (void*)&dofscroll },
|
||||
{"tabsize", "ts", VINT, V_DISPLAY, (void*)&tabsize },
|
||||
{"autoindent","ai", VBOOL, 0, (void*)&autoindent },
|
||||
{"autocopy", "ac", VBOOL, 0, (void*)&autocopy },
|
||||
{"autowrite", "aw", VBOOL, 0, (void*)&autowrite },
|
||||
{"wrapscan", "ws", VBOOL, 0, (void*)&wrapscan },
|
||||
{"overwrite", "ow", VBOOL, 0, (void*)&overwrite },
|
||||
{"beautify", "be", VBOOL, 0, (void*)&beautify },
|
||||
{"list", "", VBOOL, V_DISPLAY, (void*)&list },
|
||||
{"magic", "", VBOOL, 0, (void*)&magic },
|
||||
{"ignorecase","ic", VBOOL, 0, (void*)&ignorecase },
|
||||
{"bell", "", VBOOL, 0, (void*)&bell },
|
||||
#if OS_ATARI
|
||||
{"mapslash", "ms", VBOOL, 0, (void*)&mapslash },
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* For movement routines */
|
||||
int setstep[2] = {-1,1};
|
||||
|
||||
/* Where the last diddling left us */
|
||||
struct coord curpos={0, 0};
|
||||
|
||||
/* initialize the buffer */
|
||||
int bufmax = 0, /* End of file here */
|
||||
lstart = 0, lend = 0, /* Start & end of current line */
|
||||
ptop = 0, pend = 0, /* Top & bottom of CRT window */
|
||||
curr = 0, /* Global cursor pos */
|
||||
xp = 0, yp = 0, /* Cursor window position */
|
||||
count = 0; /* Latest count */
|
||||
|
||||
bool modified= NO, /* File has been modified */
|
||||
readonly= NO, /* is this file readonly? */
|
||||
needchar= YES, /* Peekc flag */
|
||||
deranged= NO, /* Up-arrow || down-arrow left xpos in Oz. */
|
||||
indirect= NO, /* Reading from an indirect file?? */
|
||||
redoing = NO, /* doing a redo? */
|
||||
xerox = NO, /* making a redo buffer? */
|
||||
newfile = YES, /* Editing a new file? */
|
||||
newline = NO, /* Last insert/delete included a EOL */
|
||||
lineonly= NO, /* Dumb terminal? */
|
||||
zotscreen=NO, /* ask for [more] in execmode */
|
||||
diddled = NO; /* force new window in editcore */
|
||||
|
||||
int macro = -1; /* Index into MCR */
|
||||
char lsearch = 0; /* for N and n'ing... */
|
||||
|
||||
/* movement, command codes */
|
||||
|
||||
cmdtype movemap[256]={
|
||||
/*^@*/ BAD_COMMAND,
|
||||
/*^A*/ DEBUG_C,
|
||||
/*^B*/ HARDMACRO,
|
||||
/*^C*/ BAD_COMMAND,
|
||||
/*^D*/ WINDOW_UP,
|
||||
/*^E*/ HARDMACRO,
|
||||
/*^F*/ HARDMACRO,
|
||||
/*^G*/ FILE_C,
|
||||
/*^H*/ GO_LEFT, /* also leftarrow */
|
||||
/*^I*/ REDRAW_C,
|
||||
/*^J*/ GO_DOWN, /* also downarrow */
|
||||
/*^K*/ GO_UP, /* also uparrow */
|
||||
/*^L*/ GO_RIGHT, /* also rightarrow */
|
||||
/*^M*/ CR_FWD,
|
||||
/*^N*/ BAD_COMMAND,
|
||||
/*^O*/ BAD_COMMAND,
|
||||
/*^P*/ BAD_COMMAND,
|
||||
/*^Q*/ BAD_COMMAND,
|
||||
/*^R*/ BAD_COMMAND,
|
||||
/*^S*/ BAD_COMMAND,
|
||||
/*^T*/ BAD_COMMAND,
|
||||
/*^U*/ WINDOW_DOWN,
|
||||
/*^V*/ BAD_COMMAND,
|
||||
/*^W*/ BAD_COMMAND,
|
||||
/*^X*/ BAD_COMMAND,
|
||||
/*^Y*/ HARDMACRO,
|
||||
/*^Z*/ BAD_COMMAND,
|
||||
/*^[*/ BAD_COMMAND,
|
||||
/*^\*/ BAD_COMMAND,
|
||||
/*^]*/ BAD_COMMAND,
|
||||
/*^^*/ BAD_COMMAND,
|
||||
/*^_*/ BAD_COMMAND,
|
||||
/* */ GO_RIGHT,
|
||||
/*! */ EXEC_C,
|
||||
/*" */ BAD_COMMAND,
|
||||
/*# */ BAD_COMMAND,
|
||||
/*$ */ TO_EOL,
|
||||
/*% */ MATCHEXPR,
|
||||
/*& */ RESUBST_C,
|
||||
/*\ */ TO_MARK_LINE,
|
||||
/*( */ SENT_BACK,
|
||||
/*) */ SENT_FWD,
|
||||
/** */ BAD_COMMAND,
|
||||
/*+ */ CR_FWD,
|
||||
/*, */ BAD_COMMAND,
|
||||
/*- */ CR_BACK,
|
||||
/*. */ REDO_C,
|
||||
/*/ */ PATT_FWD,
|
||||
/*0 */ TO_COL,
|
||||
/*1 */ BAD_COMMAND,
|
||||
/*2 */ BAD_COMMAND,
|
||||
/*3 */ BAD_COMMAND,
|
||||
/*4 */ BAD_COMMAND,
|
||||
/*5 */ BAD_COMMAND,
|
||||
/*6 */ BAD_COMMAND,
|
||||
/*7 */ BAD_COMMAND,
|
||||
/*8 */ BAD_COMMAND,
|
||||
/*9 */ BAD_COMMAND,
|
||||
/*: */ COLIN_C,
|
||||
/*; */ BAD_COMMAND,
|
||||
/*< */ ADJUST_C,
|
||||
/*= */ BAD_COMMAND,
|
||||
/*> */ ADJUST_C,
|
||||
/*? */ PATT_BACK,
|
||||
/*@ */ BAD_COMMAND,
|
||||
/*A */ A_AT_END,
|
||||
/*B */ BACK_WD,
|
||||
/*C */ HARDMACRO,
|
||||
/*D */ HARDMACRO,
|
||||
/*E */ BAD_COMMAND,
|
||||
/*F */ BACK_CHAR,
|
||||
/*G */ GLOBAL_LINE,
|
||||
/*H */ PAGE_BEGIN,
|
||||
/*I */ I_AT_NONWHITE,
|
||||
/*J */ JOIN_C,
|
||||
/*K */ BAD_COMMAND,
|
||||
/*L */ PAGE_END,
|
||||
/*M */ PAGE_MIDDLE,
|
||||
/*N */ BSEARCH,
|
||||
/*O */ OPENUP_C,
|
||||
/*P */ PUT_AFTER,
|
||||
/*Q */ EDIT_C,
|
||||
/*R */ BIG_REPL_C,
|
||||
/*S */ BAD_COMMAND,
|
||||
/*T */ BACKTO_CHAR,
|
||||
/*U */ BAD_COMMAND,
|
||||
/*V */ BAD_COMMAND,
|
||||
/*W */ FORWD,
|
||||
/*X */ HARDMACRO,
|
||||
/*Y */ HARDMACRO,
|
||||
/*Z */ ZZ_C,
|
||||
/*[ */ BAD_COMMAND,
|
||||
/*\ */ BAD_COMMAND,
|
||||
/*] */ BAD_COMMAND,
|
||||
/*^ */ NOTWHITE,
|
||||
/*_ */ BAD_COMMAND,
|
||||
/*` */ TO_MARK,
|
||||
/*a */ APPEND_C,
|
||||
/*b */ BACK_WD,
|
||||
/*c */ CHANGE_C,
|
||||
/*d */ DELETE_C,
|
||||
/*e */ FORWD,
|
||||
/*f */ TO_CHAR,
|
||||
/*g */ BAD_COMMAND,
|
||||
/*h */ GO_LEFT,
|
||||
/*i */ INSERT_C,
|
||||
/*j */ GO_DOWN,
|
||||
/*k */ GO_UP,
|
||||
/*l */ GO_RIGHT,
|
||||
/*m */ MARKER_C,
|
||||
/*n */ FSEARCH,
|
||||
/*o */ OPEN_C,
|
||||
/*p */ PUT_BEFORE,
|
||||
/*q */ BAD_COMMAND,
|
||||
/*r */ REPLACE_C,
|
||||
/*s */ HARDMACRO,
|
||||
/*t */ UPTO_CHAR,
|
||||
/*u */ UNDO_C,
|
||||
/*v */ BTO_WD,
|
||||
/*w */ TO_WD,
|
||||
/*x */ HARDMACRO,
|
||||
/*y */ YANK_C,
|
||||
/*z */ REWINDOW,
|
||||
/*{ */ PARA_BACK,
|
||||
/*| */ TO_COL,
|
||||
/*} */ PARA_FWD,
|
||||
/*~ */ TWIDDLE_C,
|
||||
/*^?*/ BAD_COMMAND,
|
||||
/*80*/ BAD_COMMAND,
|
||||
/*81*/ BAD_COMMAND,
|
||||
/*82*/ BAD_COMMAND,
|
||||
/*83*/ BAD_COMMAND,
|
||||
/*84*/ BAD_COMMAND,
|
||||
/*85*/ BAD_COMMAND,
|
||||
/*x6*/ BAD_COMMAND,
|
||||
/*x7*/ BAD_COMMAND,
|
||||
/*x8*/ BAD_COMMAND,
|
||||
/*x9*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND,
|
||||
/*xx*/ BAD_COMMAND
|
||||
};
|
||||
36
src/cmd/levee/grep.h
Normal file
36
src/cmd/levee/grep.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#define LEND '$'
|
||||
#define LSTART '^'
|
||||
#define LITCHAR 'c'
|
||||
#define ANY '.'
|
||||
#define CCL '['
|
||||
#define NCCL '!'
|
||||
#define DASH '-'
|
||||
#define CCLEND ']'
|
||||
#define NEGATE '^'
|
||||
#define CLOSURE '*'
|
||||
#define ESCAPE '\\'
|
||||
#define TOKENB '<'
|
||||
#define TOKENE '>'
|
||||
|
||||
#define ARGSTART '('
|
||||
#define ARGEND ')'
|
||||
#define AMPERSAND '&'
|
||||
156
src/cmd/levee/insert.c
Normal file
156
src/cmd/levee/insert.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
int PROC
|
||||
insertion(count, openflag, dp, yp, visual)
|
||||
int count, openflag, *dp, *yp;
|
||||
bool visual;
|
||||
{
|
||||
char cmd, c;
|
||||
int rp; /* number of spaces to diddle */
|
||||
int ts, ss; /* tabs && spaces to insert */
|
||||
register int cp; /* current position */
|
||||
int i; /* random index */
|
||||
int endd; /* last open place */
|
||||
register int rsize; /* size of upper buffer */
|
||||
int currDLE = 0; /* what DLE is now */
|
||||
int len; /* full insert size */
|
||||
bool Dflag;
|
||||
|
||||
if (openflag != 0) { /* opening a line above || below */
|
||||
if (openflag<0 && bufmax>0 && curr<bufmax) {
|
||||
curr = 1+lend;
|
||||
if (visual)
|
||||
zwrite("\n", 1);
|
||||
}
|
||||
else { /* open above current line */
|
||||
(*yp)--;
|
||||
curr = lstart;
|
||||
}
|
||||
if (autoindent)
|
||||
currDLE = findDLE(lstart, &i, skipws(lstart),0);
|
||||
if (visual) {
|
||||
#if TTY_VT52
|
||||
if (OL) {
|
||||
#else
|
||||
if (OL && (*yp) < LINES-2) {
|
||||
#endif
|
||||
strput(OL);
|
||||
(*yp)++;
|
||||
curpos.y = *yp;
|
||||
}
|
||||
else {
|
||||
mvcur(1+(*yp), 0);
|
||||
strput(CE);
|
||||
}
|
||||
}
|
||||
mvcur(-1, currDLE);
|
||||
}
|
||||
else {
|
||||
if (autoindent)
|
||||
currDLE = findDLE(lstart, &i, curr, 0);
|
||||
if (curr == i) {
|
||||
if (!delete_to_undo(&undo, lstart, i-lstart))
|
||||
return(-1);
|
||||
curr = lstart;
|
||||
}
|
||||
}
|
||||
|
||||
rsize = (bufmax-curr); /* amount of stuff above curr */
|
||||
endd = SIZE - rsize; /* split the buffer */
|
||||
if (rsize > 0)
|
||||
moveright(&core[curr], &core[endd], rsize);
|
||||
|
||||
cp = curr;
|
||||
do { /* Insert loop */
|
||||
Dflag = (cp==0 || core[cp-1]==EOL);
|
||||
do {
|
||||
if (Dflag)
|
||||
while ((cmd=peekc()) == '' || cmd == '') {
|
||||
if (readchar() == '')
|
||||
currDLE = min(COLS,currDLE+shiftwidth);
|
||||
else
|
||||
currDLE = max(0,currDLE-shiftwidth);
|
||||
mvcur(-1, currDLE);
|
||||
}
|
||||
} while (!(c = line(core, cp, endd-1, &len)));
|
||||
if (Dflag && (len > 0 || c == ESC)) {
|
||||
/* makeDLE : optimize leading whitespace for insert */
|
||||
currDLE = findDLE(cp, &rp, cp+len, currDLE);
|
||||
if (rp > cp) {
|
||||
len -= (rp-cp);
|
||||
moveleft(&core[rp], &core[cp], len); /* squash whitespace */
|
||||
}
|
||||
if (currDLE > 0) { /* create DLE indent */
|
||||
ts = currDLE / tabsize;
|
||||
ss = currDLE % tabsize;
|
||||
moveright(&core[cp], &core[cp+ts+ss], len);
|
||||
len += (ts+ss);
|
||||
fillchar(&core[cp ], ts, TAB);
|
||||
fillchar(&core[cp+ts], ss, 32);
|
||||
}
|
||||
}
|
||||
cp += len;
|
||||
if (c == EOL) { /* Diddle-Diddle */
|
||||
core[cp++] = EOL; /* add in a \n */
|
||||
strput(CE); /* clear this line */
|
||||
println();
|
||||
if (visual) {
|
||||
#if OS_RMX
|
||||
/* at OL at bottom kludge... */
|
||||
if (OL && (*yp) < LINES-2) {
|
||||
#else
|
||||
if (OL) {
|
||||
#endif
|
||||
strput(OL);
|
||||
(*yp)++;
|
||||
}
|
||||
else
|
||||
strput(CE);
|
||||
}
|
||||
if (!autoindent) /* reset currDLE? */
|
||||
currDLE = 0;
|
||||
mvcur(-1, currDLE);
|
||||
}
|
||||
} while (c != ESC && cp <= endd-INSSIZE);
|
||||
*dp = cp; /* start display here */
|
||||
|
||||
if (count > 1) { /* repeated insertion */
|
||||
len = cp-curr;
|
||||
if ((count-1)*len < endd-cp)
|
||||
for (i = 1;i <count;i++) {
|
||||
moveright(&core[cp-len], &core[cp], len);
|
||||
cp += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (openflag != 0 /* open or insert at end of buffer */
|
||||
|| (rsize < 1 && cp > curr && core[cp-1] != EOL))
|
||||
core[cp++] = EOL;
|
||||
len = cp-curr;
|
||||
|
||||
if (rsize > 0) /* if not at end of buffer, stitch things together */
|
||||
moveleft(&core[endd], &core[cp], rsize);
|
||||
insert_to_undo(&undo, curr, len);
|
||||
core[bufmax] = EOL;
|
||||
return(cp);
|
||||
}
|
||||
386
src/cmd/levee/levee.h
Normal file
386
src/cmd/levee/levee.h
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1980-2008 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*
|
||||
* Levee v3.C
|
||||
* C version for Unix/Atari ST/MS-DOS/OS-2/FlexOs/iRMX/etc
|
||||
* Pascal version for UCSD Pascal 4.X
|
||||
*
|
||||
* written fall 82' - now (approx) by David L. Parsons.
|
||||
*
|
||||
* many patches, suggestions,
|
||||
* and impractical design goals by:
|
||||
* Jim Bolland,
|
||||
* John Plocher,
|
||||
* John Tainter
|
||||
*/
|
||||
#ifndef LEVEE_D
|
||||
|
||||
#define LEVEE_D
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1) /* Nobody defines TRUE & FALSE, so I will do */
|
||||
#define FALSE (0) /* it myself */
|
||||
#endif
|
||||
|
||||
#define HANDLE int /* default file handle type */
|
||||
|
||||
#define PROC /* for magic function types (MSDOS) */
|
||||
#define VOID void /* ancient creaking C compilers won't understand void */
|
||||
|
||||
/*
|
||||
* Compilation defines for different systems.
|
||||
*/
|
||||
|
||||
#if OS_ATARI
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define void int /* Alcyon C don't know void */
|
||||
|
||||
/* extractions from osbind.h */
|
||||
#define OPEN_OLD(n) gemdos(0x3d,n,/*open mode*/0)
|
||||
#define OPEN_NEW(n) gemdos(0x3c,n,/*permissions*/0)
|
||||
#define CLOSE_FILE(f) gemdos(0x3e,f)
|
||||
#define SEEK_POSITION(f,o,m) gemdos(0x42,(long)(o),f,m)
|
||||
#define READ_TEXT(f,b,c) gemdos(0x3f,f,(long)(c),b)
|
||||
#define WRITE_TEXT(f,b,c) gemdos(0x40,f,(long)(c),b)
|
||||
|
||||
extern char *malloc();
|
||||
extern long gemdos();
|
||||
|
||||
#endif /*OS_ATARI*/
|
||||
|
||||
#if OS_RMX
|
||||
#include <:inc:stdio.h>
|
||||
#include <:inc:udi.h>
|
||||
|
||||
#define OPEN_OLD(n) open(n, /*open mode*/0)
|
||||
#define OPEN_NEW(n) creat(n,/*permissions*/0)
|
||||
#define CLOSE_FILE(f) close(f)
|
||||
#define SEEK_POSITION(f,o,m) lseek((f),(long)(o),(m))
|
||||
#define READ_TEXT(f,p,c) read((f),(p),(unsigned)(c))
|
||||
#define WRITE_TEXT(f,p,c) write((f),(p),(unsigned)(c))
|
||||
|
||||
#define zwrite(p,s) write(1,(p), (unsigned)(s))
|
||||
|
||||
#endif /*OS_RMX*/
|
||||
|
||||
#if OS_DOS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define OPEN_OLD(n) open(n, O_RDONLY|O_BINARY)
|
||||
#define OPEN_NEW(n) open(n, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666)
|
||||
#define CLOSE_FILE(f) close(f)
|
||||
#define SEEK_POSITION(f,o,m) lseek(f, (long)(o), (m))
|
||||
#define READ_TEXT(f,p,c) read(f, p, (int)(c))
|
||||
#define WRITE_TEXT(f,p,c) write(f, p, (int)(c))
|
||||
|
||||
#define zwrite(p,s) WRITE_TEXT(fileno(stdout), p, s)
|
||||
|
||||
#undef PROC
|
||||
#define PROC _fastcall
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#endif /*OS_DOS*/
|
||||
|
||||
#if OS_UNIX
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define OPEN_OLD(n) open(n, O_RDONLY)
|
||||
#define OPEN_NEW(n) open(n, O_WRONLY|O_CREAT|O_TRUNC, 0666)
|
||||
#define CLOSE_FILE(f) close(f)
|
||||
#define SEEK_POSITION(f,o,m) lseek(f, (long)(o), (m))
|
||||
#define READ_TEXT(f,p,c) read(f, p, (int)(c))
|
||||
#define WRITE_TEXT(f,p,c) write(f, p, (int)(c))
|
||||
|
||||
#define zwrite(p,s) fwrite(p, 1, s, stdout)
|
||||
|
||||
#endif /*OS_UNIX*/
|
||||
|
||||
#if OS_FLEXOS
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define OPEN_OLD(n) s_open(m,0x08) /* note reversed parameters! */
|
||||
#define OPEN_NEW(n) s_create(0,0,n,0,0/*mode*/,0)
|
||||
#define CLOSE_FILE(f) s_close(0,f) /* Full close on handle */
|
||||
#define SEEK_POSITION(f,o,m) s_seek((m&03)<<9, f, o)
|
||||
#define READ_TEXT(f,p,c) s_read(0x0100,(long)(f),p,(long)(c),0L)
|
||||
#define WRITE_TEXT(f,p,c) s_write(0x0101,(long)(f),p,(long)(c),0L)
|
||||
|
||||
#define zwrite(p,s) s_write(0x0101, 1L, p, (long)(s),0L)
|
||||
|
||||
#define unlink(n) s_delete(0, n)
|
||||
#define rename(a,b) s_rename(0, a, b)
|
||||
|
||||
/* OPEN_OLD mode flags */
|
||||
|
||||
#undef HANDLE
|
||||
#define HANDLE long
|
||||
|
||||
#endif /*OS_FLEXOS*/
|
||||
|
||||
#define bool int
|
||||
|
||||
/* ttydef stuff */
|
||||
#if !(OS_ATARI | USE_TERMCAP)
|
||||
|
||||
#ifndef LINES
|
||||
#define LINES 25
|
||||
#endif /*LINES*/
|
||||
#define COLS 79
|
||||
|
||||
#endif
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define UPARROW 11
|
||||
#define DNARROW 10
|
||||
#define LTARROW erase
|
||||
#define RTARROW 12
|
||||
|
||||
#if !USE_TERMCAP
|
||||
#define CA TRUE
|
||||
#if !(OS_DOS||OS_FLEXOS)
|
||||
#define canUPSCROLL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* nospecific stuff */
|
||||
#define MAGICNUMBER 42
|
||||
#define hell_freezes_over FALSE
|
||||
#define BUGS 7 /* sometime when you least expect it.. */
|
||||
|
||||
#define DW 23 /* Delete Word */
|
||||
#define EOL 10 /* End Of Line */
|
||||
#define DLE 16 /* Space compression lead-in */
|
||||
#define ESC 27 /* Escape */
|
||||
|
||||
/* hardwired line kill and erase character for non-unix machines */
|
||||
#define DEL 21 /* ^U */
|
||||
#if RMX
|
||||
#define ERASE 127
|
||||
#else
|
||||
#define ERASE 8 /* ^H */
|
||||
#endif
|
||||
|
||||
#define TAB 9
|
||||
|
||||
/* variable types */
|
||||
#define VBOOL 0
|
||||
#define VINT 1
|
||||
#define VSTR 2
|
||||
|
||||
#define ERR (-1)
|
||||
|
||||
/* Undostack commands */
|
||||
#define U_ADDC 'A'
|
||||
#define U_MOVEC 'M'
|
||||
#define U_DELC 'D'
|
||||
|
||||
/* magic things for find */
|
||||
#define MAXPAT ((int)300)
|
||||
|
||||
/* exec mode commands */
|
||||
#define EX_CR (ERR-1)
|
||||
#define EX_PR 0
|
||||
#define EX_QUIT 1
|
||||
#define EX_READ 2
|
||||
#define EX_EDIT 3
|
||||
#define EX_WRITE 4
|
||||
#define EX_WQ 5
|
||||
#define EX_NEXT 6
|
||||
#define EX_SUBS 7
|
||||
#define EX_XIT 8
|
||||
#define EX_FILE 9
|
||||
#define EX_SET 10
|
||||
#define EX_RM 11
|
||||
#define EX_PREV 12
|
||||
#define EX_DELETE 13
|
||||
#define EX_LINE 14
|
||||
#define EX_YANK 15
|
||||
#define EX_PUT 16
|
||||
#define EX_VI 17
|
||||
#define EX_EX 18
|
||||
#define EX_INSERT 19
|
||||
#define EX_OPEN 20
|
||||
#define EX_CHANGE 21
|
||||
#define EX_UNDO 22
|
||||
#define EX_ESCAPE 23
|
||||
#define EX_MAP 24
|
||||
#define EX_UNMAP 25
|
||||
#define EX_SOURCE 26
|
||||
#define EX_VERSION 27
|
||||
#define EX_ARGS 28
|
||||
#define EX_REWIND 29
|
||||
|
||||
/* movement return states */
|
||||
#define LEGALMOVE 0
|
||||
#define BADMOVE 1
|
||||
#define ESCAPED 2
|
||||
#define findstates char
|
||||
|
||||
/* command codes */
|
||||
#define BAD_COMMAND 0
|
||||
/*visual movement*/
|
||||
#define GO_RIGHT 1
|
||||
#define GO_LEFT 2
|
||||
#define GO_UP 3
|
||||
#define GO_DOWN 4
|
||||
#define FORWD 5
|
||||
#define TO_WD 6
|
||||
#define BACK_WD 7
|
||||
#define BTO_WD 8
|
||||
#define NOTWHITE 9
|
||||
#define TO_COL 10
|
||||
#define TO_EOL 11
|
||||
#define MATCHEXPR 12
|
||||
#define TO_CHAR 13
|
||||
#define UPTO_CHAR 14
|
||||
#define BACK_CHAR 15
|
||||
#define BACKTO_CHAR 16
|
||||
#define SENT_FWD 17
|
||||
#define SENT_BACK 18
|
||||
#define PAGE_BEGIN 19
|
||||
#define PAGE_END 20
|
||||
#define PAGE_MIDDLE 21
|
||||
#define CR_FWD 22
|
||||
#define CR_BACK 23
|
||||
#define PATT_FWD 24
|
||||
#define PATT_BACK 25
|
||||
#define FSEARCH 26
|
||||
#define BSEARCH 27
|
||||
#define GLOBAL_LINE 28
|
||||
#define TO_MARK 29
|
||||
#define TO_MARK_LINE 30
|
||||
#define PARA_FWD 31
|
||||
#define PARA_BACK 32
|
||||
/*modifications*/
|
||||
#define DELETE_C 39
|
||||
#define EXEC_C 40
|
||||
#define ADJUST_C 41
|
||||
#define CHANGE_C 42
|
||||
#define YANK_C 43
|
||||
#define INSERT_C 44
|
||||
#define APPEND_C 45
|
||||
#define I_AT_NONWHITE 46
|
||||
#define A_AT_END 47
|
||||
#define OPEN_C 48
|
||||
#define OPENUP_C 49
|
||||
#define REPLACE_C 50
|
||||
#define TWIDDLE_C 51
|
||||
#define RESUBST_C 52
|
||||
#define JOIN_C 53
|
||||
#define UNDO_C 54
|
||||
#define BIG_REPL_C 55
|
||||
#define PUT_BEFORE 56
|
||||
#define PUT_AFTER 57
|
||||
/*everything else*/
|
||||
#define HARDMACRO 70
|
||||
#define REWINDOW 71
|
||||
#define ZZ_C 72
|
||||
#define DEBUG_C 73
|
||||
#define FILE_C 74
|
||||
#define WINDOW_UP 75
|
||||
#define WINDOW_DOWN 76
|
||||
#define REDRAW_C 77
|
||||
#define MARKER_C 78
|
||||
#define REDO_C 79
|
||||
#define EDIT_C 80
|
||||
#define COLIN_C 81
|
||||
/*macros*/
|
||||
#define SOFTMACRO 100
|
||||
#define INSMACRO 101
|
||||
#define cmdtype char
|
||||
|
||||
/* exec mode states */
|
||||
#define E_VISUAL 0
|
||||
#define E_INIT 1
|
||||
#define E_EDIT 2
|
||||
#define exec_type char
|
||||
|
||||
/* various sizes */
|
||||
#define INSSIZE ((int)80) /* Insert string size */
|
||||
#define FSIZE ((int)39) /* File string size */
|
||||
#ifndef SIZE
|
||||
# define SIZE ((int)32760) /* Edit buffer size */
|
||||
#endif
|
||||
|
||||
#define SBUFSIZE ((int)4096) /* Incore yank buffer size */
|
||||
#define MAXMACROS 32 /* Maximum # of macros */
|
||||
#define NMACROS 9 /* Nexting level for macros */
|
||||
|
||||
#define PAGESIZE ((int)1024) /* Bytes per block */
|
||||
|
||||
struct coord { /* Screen Coordinate */
|
||||
int x,y;
|
||||
};
|
||||
|
||||
struct ybuf { /* Yank Buffer */
|
||||
int size; /* Bytes yanked */
|
||||
bool lines, /* Yanked whole lines? */
|
||||
has_eol; /* Yanked a EOL? */
|
||||
char stuff[SBUFSIZE]; /* The stuff */
|
||||
};
|
||||
|
||||
struct undostack { /* Undo Stack Descriptor */
|
||||
int blockp, /* block address of core block */
|
||||
ptr; /* offset within coreblock */
|
||||
int coreblock[PAGESIZE]; /* core block */
|
||||
};
|
||||
|
||||
union optionrec { /* Black Magic Option Structure */
|
||||
int valu; /* if integer, the value */
|
||||
char *strp; /* or if string, a pointer to it */
|
||||
};
|
||||
|
||||
struct macrecord { /* Macro Descriptor */
|
||||
char token; /* Character mapped */
|
||||
cmdtype oldmap; /* Old value in movemap */
|
||||
char *m_text; /* Replacement text */
|
||||
};
|
||||
|
||||
struct tmacro { /* For running a macro */
|
||||
char *mtext, /* Pointer to macro text */
|
||||
*ip; /* Pointer into macro text */
|
||||
int m_iter; /* Number of times to execute */
|
||||
};
|
||||
|
||||
#define V_CONST 1 /* this option cannot be modified */
|
||||
#define V_DISPLAY 2 /* this option affects the display */
|
||||
|
||||
struct variable { /* Settable Variable Record */
|
||||
char *v_name; /* full name */
|
||||
char *v_abbr; /* abbreviated name */
|
||||
int v_tipe; /* what kind of variable */
|
||||
int v_flags; /* special attributes... */
|
||||
union optionrec *u; /* pointer to it */
|
||||
};
|
||||
#endif /*LEVEE_D*/
|
||||
955
src/cmd/levee/lv.1
Normal file
955
src/cmd/levee/lv.1
Normal file
@@ -0,0 +1,955 @@
|
||||
.TH LEVEE 1 "29 August 1998" "Mastodon Linux"
|
||||
.SH NAME
|
||||
.B levee
|
||||
\-
|
||||
A Screen Oriented Editor.
|
||||
.SH SYNOPSIS
|
||||
.B levee
|
||||
[\fI+address\fR] [\fIfile \fB...\fR]
|
||||
.SH DESCRIPTION
|
||||
Levee is a screen oriented editor based on the Unix editor
|
||||
"vi". It provides a terse, powerful way to enter and edit text
|
||||
(however, if you want a word-processor, you're better off with
|
||||
WordStar.)
|
||||
|
||||
Levee is a moded editor. It operates in 3 modes -- visual,
|
||||
command, and insert. Most of the editing work is done is visual
|
||||
mode, file reading and writing is done in command mode, and
|
||||
insert mode does what you would expect.
|
||||
.PP
|
||||
When you enter Levee, you may specify an address to start
|
||||
editing at. These addresses are in the same format as command
|
||||
mode addresses, except that a naked + will put you at the very
|
||||
end of the file.
|
||||
.PP
|
||||
Levee is copyright (c) 1982-2008 by David L. Parsons. (see
|
||||
the notice at the end of this document for distribution terms)
|
||||
|
||||
.SH "COMMAND MODE COMMANDS"
|
||||
|
||||
These commands are used for editing new files, writing
|
||||
modified files, changing options, doing substitutions, and
|
||||
a subset of the visual commands. They take as input whole
|
||||
lines, terminated by return (to execute), or escape (to
|
||||
abort.)
|
||||
|
||||
Command mode is reached by typing ":" or "Q" from visual
|
||||
mode. If you enter command mode by typing ":", Levee will
|
||||
execute one command, then return to visual mode after
|
||||
prompting you with "[more]". If you type anything except
|
||||
a space or return, Levee will accept another command, and so
|
||||
forth. If, however, you enter command mode via "Q", Levee
|
||||
will remain in command mode until you enter the "visual"
|
||||
command.
|
||||
|
||||
|
||||
.SS "A NOTE ON COMMAND SYNTAX"
|
||||
.PP
|
||||
A command may be preceded by an optional line-range. If
|
||||
you do not provide a line-range, Levee will use the default
|
||||
line-range shown by the command. A line-range is one or two
|
||||
address specifications in the following format:
|
||||
|
||||
.RS
|
||||
(\fB.\fR|\fB$\fR|\fB'x\fR|\fB#\fR) [ (\fB+\fR|\fB-\fR) (\fB/\fIpatt\fB\fB/\fR|\fB?\fIpatt\fB?\fR|\fB#\fR) ]
|
||||
.TP
|
||||
.B \.
|
||||
current line.
|
||||
.TP
|
||||
.B $
|
||||
last line.
|
||||
.TP
|
||||
.B 'x
|
||||
the line with mark x on it.
|
||||
.TP
|
||||
.B #
|
||||
line #.
|
||||
.RE
|
||||
|
||||
.PP
|
||||
For example, ".-5,.+5p" will print every line within ten
|
||||
lines of the current line. "$-5" is the fifth line from the
|
||||
end of the file, and "/end/+2" is the second line past the
|
||||
next occurrence of the pattern "end". Patterns may be
|
||||
regular expressions (see below.)
|
||||
|
||||
Also, a naked line-range will set the current line to
|
||||
the first line in the range and print all the lines in that
|
||||
range. "1,10" sets the current line to 1, then prints lines
|
||||
1 to 10.
|
||||
|
||||
If you specify a non-existent line in a range, the command
|
||||
will abort and Levee will tell you "bad address".
|
||||
|
||||
.SS "Command mode commands"
|
||||
|
||||
.TP
|
||||
.B args
|
||||
show the current argument list, if one exists. The file that you
|
||||
are currently editing will be framed by '[' and ']'.
|
||||
|
||||
.TP
|
||||
.IB (.,.) change
|
||||
delete lines, then enter insert mode.
|
||||
|
||||
.TP
|
||||
.IB (.,.) delete
|
||||
delete lines. Deleted lines are stored in a Yank Buffer for
|
||||
later putback with "put".
|
||||
|
||||
.TP
|
||||
.B "edit[!] [file]"
|
||||
Discard the current file and start editing a new one. If
|
||||
changes were made to the current file, you must enter "edit!"
|
||||
to force Levee to discard the changes. If you do not specify
|
||||
a filename, Levee will try to reedit the current filename.
|
||||
|
||||
When Levee reads in a new file, it will tell you how many
|
||||
bytes it read in, or [overflow] if the file is larger than the
|
||||
internal buffer (256000 bytes on most platforms; 20k on USCD
|
||||
Pascal.)
|
||||
|
||||
.TP
|
||||
.B execmode
|
||||
Remain in command mode until you use the "visual" command.
|
||||
|
||||
.TP
|
||||
.BI file [name]
|
||||
Echo what the current filename is, its status, and the current
|
||||
line. If you provide it with a name, it will change the filename
|
||||
to that.
|
||||
|
||||
.TP
|
||||
.IB (.) insert
|
||||
Insert text above the current line. If you specify a line number,
|
||||
Levee will make that the current line, then insert above it.
|
||||
|
||||
.RS
|
||||
.SS "Insert mode commands"
|
||||
.TP
|
||||
.B ^W
|
||||
back over the last word you entered.
|
||||
.TP
|
||||
.B ^H
|
||||
back over one character.
|
||||
.TP
|
||||
.B ^U
|
||||
back over all input on this line.
|
||||
.TP
|
||||
.B ^V
|
||||
escape the next character typed. (For example,
|
||||
.B ^V^H
|
||||
will put a ^H into the file.)
|
||||
.TP
|
||||
.B ESC
|
||||
exit insert mode.
|
||||
.TP
|
||||
.B ^D
|
||||
If at start of line, reduce indentation 'shiftwidth' columns.
|
||||
.TP
|
||||
.B ^T
|
||||
If at start of line, increase indentation 'shiftwidth' columns.
|
||||
.RE
|
||||
|
||||
.PP
|
||||
|
||||
When in insert mode, Levee will not allow you to enter any control
|
||||
characters except return and tab. Return ends input on this line and
|
||||
opens a new line for input.
|
||||
|
||||
.TP
|
||||
.BI map[!] [key [text]]
|
||||
Define/list macros. There are 3 forms of map:
|
||||
.TP
|
||||
.I map.
|
||||
This lists all the active macros.
|
||||
.TP
|
||||
.IR map (key).
|
||||
This shows the macro associated with (key), if any.
|
||||
.TP
|
||||
.IR map "(key) (text)"
|
||||
This maps (key) to (text). You may map any
|
||||
key except ":" and escape. In the normal
|
||||
form (map), the macro will be effective
|
||||
in visual mode, but in the alternate form,
|
||||
(map!), the macro will be effective in
|
||||
insert and command modes.
|
||||
|
||||
.PP
|
||||
For example, if you map!ped return to "hello world", every time
|
||||
you entered a return in command or visual mode, the string "hello
|
||||
world" would pop up.
|
||||
|
||||
.TP
|
||||
.BI next [file ...]
|
||||
Edit the next file in the arglist, or edit a new arglist. Levee
|
||||
takes its initial arglist off the command line when you execute it.
|
||||
If "autowrite" is set, Levee will write out the changes to the
|
||||
current file before editing the next one.
|
||||
|
||||
.TP
|
||||
.IB (.) open
|
||||
Insert below the current line. Otherwise just like insert.
|
||||
|
||||
.TP
|
||||
.B previous
|
||||
Edit the previous file in the arglist. Otherwise, like next.
|
||||
|
||||
.TP
|
||||
.IB (.,.) print
|
||||
Display lines without changing the current line.
|
||||
|
||||
.TP
|
||||
.IB (.) put
|
||||
Put the contents of the yank buffer back on the line below
|
||||
the current line. If you specify a line, it resets the current
|
||||
line, then puts the yank buffer back. The yank buffer is filled
|
||||
by the delete, change, or yank commands. Put does not destroy
|
||||
the yank buffer, so you may put back text multiple times.
|
||||
|
||||
.TP
|
||||
.B quit[!]
|
||||
Exit Levee. If you want to discard changes, use "quit!"
|
||||
|
||||
.TP
|
||||
.IB (.) read [file]
|
||||
put the contents of 'file' after the current line.
|
||||
|
||||
.TP
|
||||
.BI rm file
|
||||
Delete 'file' from disk.
|
||||
|
||||
.TP
|
||||
.BI set [option=value]
|
||||
Set a tunable variable. Levee has a dozen or so user-definable
|
||||
variables which you can twiddle via this command. There are boolean,
|
||||
integer, and string variables that you can set. A string or integer
|
||||
variable is set by 'set xxx=yyy', a boolean variable is set via
|
||||
'set xxx' or 'set noxxx'.
|
||||
|
||||
Here are the settable variables (and abbreviations):
|
||||
.TP
|
||||
.BI tabsize (ts)
|
||||
tab stop.
|
||||
.TP
|
||||
.BI shiftwidth (sw)
|
||||
columns to shift on ^D, ^T, >>, or <<
|
||||
.TP
|
||||
.B scroll
|
||||
number of lines to scroll on ^D, ^U
|
||||
.TP
|
||||
.BI autoindent (ai)
|
||||
supply indentation during insert mode.
|
||||
.TP
|
||||
.BI autowrite (aw)
|
||||
write out changes before :next, :prev
|
||||
.TP
|
||||
.BI autocopy (ac)
|
||||
make backup copies before writing changes.
|
||||
.TP
|
||||
.B list
|
||||
display tabs as ^I, end of line as $.
|
||||
.TP
|
||||
.B magic
|
||||
use regular expressions in searches.
|
||||
.TP
|
||||
.B suffix
|
||||
if the filename does not have a . in
|
||||
it, supply the suffix. (this is the
|
||||
only string variable.)
|
||||
.TP
|
||||
.BI overwrite (ow)
|
||||
destroy old file first, then write.
|
||||
.TP
|
||||
.BI beautify (be)
|
||||
When set, Levee will not allow insert
|
||||
of any control character except tab
|
||||
and return unless you escape it with
|
||||
ctrl-V.
|
||||
.TP
|
||||
.B wrapscan
|
||||
searches wrap around end of buffer.
|
||||
.TP
|
||||
.BI ignorecase (ic)
|
||||
Ignore the case of alphabetic characters
|
||||
during searches.
|
||||
.TP
|
||||
.B "mapslash"
|
||||
(ST version only) Map '/' in filenames to
|
||||
'\\'. If the environment contains `mapslash'
|
||||
when levee is called, this variable will
|
||||
default to true, otherwise it defaults to
|
||||
false. (See the documentation for the
|
||||
Teeny-shell on how the teeny-shell interprets
|
||||
`mapslash')
|
||||
.TP
|
||||
.BI lines (li)
|
||||
(ST version only) How many lines on the display.
|
||||
This is primarily for running levee through
|
||||
the serial port - put set li=xx into your
|
||||
LVRC for a xx line terminal.
|
||||
.TP
|
||||
.BI cols (co)
|
||||
(ST version only) How many columns on the
|
||||
display. Like the lines variable, it's for
|
||||
running levee through the serial port.
|
||||
|
||||
.PP
|
||||
You may set multiple variables on one line, as in 'set ws noai'.
|
||||
To see the current settings of these variables, :set -- without any
|
||||
arguments -- will show the current settings.
|
||||
|
||||
At startup, Levee looks in the environment variable LVRC for
|
||||
a list of variables to set (GEMDOS/MS-DOS). LVRC is one line
|
||||
of the form 'option=value ...'. If you have a LVRC defined that
|
||||
is 'ts=4 ow nows', Levee will set tabsize to 4, turn on overwrite,
|
||||
and turn off wrapscan.
|
||||
|
||||
If you are using RMX, Levee looks in the file ":home:r?lvrc"
|
||||
for initialization. If you are using Osy/SWOs, Levee looks in the
|
||||
file "*.lvrc". The format of these files are different from the
|
||||
LVRC variable -- see "source" for more information.
|
||||
|
||||
.TP
|
||||
.BI source file
|
||||
Take command mode commands from 'file'. These commands can be
|
||||
any legal command, except "visual". If a error happens during
|
||||
execution of 'file', Levee abandons that level of source'ing.
|
||||
|
||||
In Osy/SWOs, there are a few differences in insert mode from
|
||||
within a sourced file. No character has special meaning except a
|
||||
line containing nothing but a period, which terminates insert mode.
|
||||
For example:
|
||||
|
||||
.RS
|
||||
:commands
|
||||
.br
|
||||
.
|
||||
.br
|
||||
.
|
||||
.br
|
||||
:insert
|
||||
.br
|
||||
blah blah blah blah blah blah
|
||||
.br
|
||||
blah blah blah blah blah blah
|
||||
.br
|
||||
blah blah blah blah blah blah
|
||||
.br
|
||||
.
|
||||
.br
|
||||
:more commands
|
||||
.RE
|
||||
|
||||
If you are running Levee under any other operating system,
|
||||
you cannot do a insert from a :source file.
|
||||
|
||||
.TP
|
||||
.B (.,.)substitute(delim)patt(delim)repl(delim)[qcpg]
|
||||
.TP
|
||||
.B (.,.)substitute&
|
||||
|
||||
Search for patt and replace it with repl. Levee will look for
|
||||
patt once on each line and replace it with repl. The delimiter
|
||||
may be any ascii character.
|
||||
|
||||
The pattern is a regular expression, just like a search pattern.
|
||||
|
||||
You may include parts of the pattern in the replacement string;
|
||||
A '&' in the replacement pattern copies in the whole source pattern,
|
||||
so if you do a 'sub/this/& and that/g', every instance of 'this'
|
||||
will be replaced with 'this and that'. Also, you may pull parts of
|
||||
the pattern out by using the \\( and \\) argument meta-characters.
|
||||
Arguments gotten by \\( & \\) are put into the replacement string
|
||||
everywhere you do a \\1..\\9 [ \\1 is the first argument you set up
|
||||
with \\( & \\) ]. So, if you want to reverse the order of two substrings,
|
||||
you can do 'sub/\\(string1\\)\\(string2\\)/\\2\\1/'.
|
||||
|
||||
substitute& redoes the last substitution.
|
||||
|
||||
Options:
|
||||
.TP
|
||||
.B q,c
|
||||
before doing the substitute, display the affected
|
||||
line and wait for you to type a character. If you
|
||||
type 'y', it will do the substitution. 'q' aborts
|
||||
the substitute, 'a' does the rest of the change
|
||||
without prompting, and 'n' does not do it.
|
||||
.TP
|
||||
.B p
|
||||
print the affected lines after the change.
|
||||
.TP
|
||||
.B g
|
||||
do the change globally. That is, do it for every
|
||||
occurence of patt on a line, rather than just
|
||||
once.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B undo
|
||||
Undo the last modification to the file (except :edit, :next, :rm,
|
||||
or :write.) You can only undo the last change to a file -- undo counts
|
||||
as a change. :undo followed by :undo does nothing to the file.
|
||||
|
||||
.TP
|
||||
.BI unmap (key)
|
||||
Undefine a macro (see map).
|
||||
|
||||
.TP
|
||||
.BI visual [list]
|
||||
If you entered command mode by "Q" or "execmode", return to
|
||||
visual mode. If you provide an argument list, it also does a
|
||||
`:next' on that list.
|
||||
|
||||
.TP
|
||||
.B version
|
||||
Show which version of levee this is.
|
||||
|
||||
.TP
|
||||
.IB (.,.) "write \fI[file]"
|
||||
Write lines to a file. If you write the everything to 'file',
|
||||
the filename is set to 'file', and if you do not specify a file,
|
||||
Levee will write to the filename.
|
||||
|
||||
.TP
|
||||
.IB (.,.) "wq \fI[file]"
|
||||
Write to a file, then quit.
|
||||
|
||||
.TP
|
||||
.IB (.,.) yank
|
||||
Yank lines from the file into the yank buffer, for later
|
||||
putback with "put".
|
||||
|
||||
.TP
|
||||
.B xit[!]
|
||||
Write changes to the current file, then exit. If there are
|
||||
more files in the arglist, use "xit!"
|
||||
|
||||
.TP
|
||||
.B ![command]
|
||||
Execute command.
|
||||
|
||||
Example:
|
||||
|
||||
.RS
|
||||
!ls => does a 'ls'.
|
||||
.RE
|
||||
|
||||
This command is available only under GEMDOS, MSDOS, RMX, and
|
||||
Unix.
|
||||
|
||||
.TP
|
||||
.B ($)=
|
||||
Give the line number of the addressed line. /end/= gives you
|
||||
the line number of the next line with a 'end' on it.
|
||||
|
||||
|
||||
.SH "VISUAL MODE COMMANDS"
|
||||
Visual mode commands move you around and modify the file.
|
||||
There are movement commands to move the cursor by a variety of
|
||||
objects.
|
||||
|
||||
In the description, a (#) means a optional count. If a
|
||||
command has a optional count, it will tell you what the count
|
||||
does in parenthesis. A (*) means that the command can be used
|
||||
in the delete, yank, and change commands.
|
||||
|
||||
Counts are made up by entering digits. If you type '45',
|
||||
the count will be set to 45. To cancel a count, type ESC.
|
||||
|
||||
This section discusses 'whitespace' occasionally.
|
||||
Whitespace is tabs, spaces, and end of line.
|
||||
|
||||
.SS "How the display works"
|
||||
|
||||
Characters are displayed on the screen as you would
|
||||
expect, except that nonprinting characters are shown as ^x,
|
||||
and tabs expand to spaces ( unless you set the option list,
|
||||
then they show as ^I.) When sitting on a control character or
|
||||
tab, the cursor is placed on the FIRST character displayed. If
|
||||
you move the cursor to any other part of them ( via j or k --
|
||||
see below), any changes will start at the next character.
|
||||
|
||||
Levee does not display a end of file marker, but lines
|
||||
past the end of the file are denoted by ~ lines.
|
||||
|
||||
If list is set, tabs display as ^I, and the end of line
|
||||
displays as $.
|
||||
|
||||
If a line is too long for the screen, it will just disappear off the end of the screen.
|
||||
|
||||
Levee will handle any screen resolution and any monospaced
|
||||
font you hand it ( if you are running in low resolution, Levee
|
||||
will give you a 25x40 window, for example.)
|
||||
|
||||
.SS "Visual mode commands"
|
||||
.TP
|
||||
.B ^A
|
||||
Show a debugging message at the bottom of the screen. This is not at
|
||||
all useful unless you are debugging the editor. Ignore it.
|
||||
|
||||
.TP
|
||||
.B (#)^D
|
||||
Scroll the screen down a half screen. If a count is specified, scroll
|
||||
down the specified number of lines.
|
||||
|
||||
.TP
|
||||
.B ^E
|
||||
Scroll down 1 line (shorthand for 1^D )
|
||||
|
||||
.TP
|
||||
.B ^G
|
||||
Show file statistics. Exactly like ':file'.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)^H
|
||||
Move the cursor left one (count) chars.
|
||||
|
||||
.TP
|
||||
.B ^I
|
||||
Redraw the screen.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)^J
|
||||
Move down one (count) lines. When you use ^J and ^K (below) to move
|
||||
up or down lines, the cursor will remain in the same column, even if
|
||||
it is in the middle of a tabstop or past the end of a line.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)^K
|
||||
Move up one (count) lines.
|
||||
.TP
|
||||
.IB (*) (#)^L
|
||||
Move right one (count) characters.
|
||||
.TP
|
||||
.IB (*) (#)^M
|
||||
Move to the first nonwhite space on the next line. If a count is specified,
|
||||
move to the first nonwhite count lines down.
|
||||
.TP
|
||||
.B (#)^U
|
||||
Scroll the screen up a half page. If a count is specified, scroll up
|
||||
count lines.
|
||||
|
||||
.TP
|
||||
.B ^Y
|
||||
Scroll the screen up 1 line (shorthand for 1^U.)
|
||||
|
||||
.TP
|
||||
.B (#)a
|
||||
Insert text AFTER the cursor. If you give a count, the insertion will
|
||||
be repeated count times ( 40i-ESC will give you a line of 40 dashes).
|
||||
|
||||
The commands in insert mode are the same for visual and command mode.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)b
|
||||
Move to the beginning of the last word (the count'th word back).
|
||||
A word is a collection of alphanumeric characters (a-z0-9$_#) or
|
||||
any other nonwhite character (i.e. anything but space, tab, eoln).
|
||||
|
||||
.TP
|
||||
.B c
|
||||
Change a object. Change deletes an object, then enters insert mode without
|
||||
redrawing the screen. When you tell it the object to be changed, Levee
|
||||
puts a '$' on the last character of the object. You cannot change
|
||||
backwards.
|
||||
|
||||
The object may be any visual mode command marked with a '(*) '. For
|
||||
example, 'c4l' will change the next 4 characters on the line to something
|
||||
else. (4cl does the same thing -- 4c4l changes the next 16 characters on
|
||||
this line.)
|
||||
|
||||
'cc' will change whole lines.
|
||||
|
||||
When changing, deleting, or yanking a object, it will be placed into
|
||||
a yank buffer, where it can be retrieved by the 'p' or 'P' commands.
|
||||
|
||||
.TP
|
||||
.B (#)d
|
||||
Delete an object. Like 'cc', 'dd' affects whole lines.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)e
|
||||
Move to the end of the current word.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)f(x)
|
||||
Find the next (count'th) occurance of a character on the current line.
|
||||
For example, if the cursor is sitting on the first character of the
|
||||
line 'abcdef', typing "ff" will put the cursor on the 'f'.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)h
|
||||
Move left one (count) characters. Exactly like ^H.
|
||||
|
||||
.TP
|
||||
.B (#)i
|
||||
Start inserting characters at the cursor. If you specify a count,
|
||||
the insertion will be duplicated count times.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)j
|
||||
Move down one (count) lines. Exactly like ^J.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)k
|
||||
Move up one (count) lines. Exactly like ^K.
|
||||
|
||||
.TP
|
||||
,B (*) (#)l
|
||||
Move right one (count) character. Exactly like ^L.
|
||||
|
||||
.TP
|
||||
.B m(x)
|
||||
Set the marker (x). There are 26 markers available (a-z). You may
|
||||
move to a marker by use of the ' or ` commands.
|
||||
|
||||
.TP
|
||||
.IB (*) n
|
||||
Find the next occurance of a search pattern. When you do a search with
|
||||
a / or ? command, Levee will remember the pattern and the direction you
|
||||
searched in. 'n' will search in the same direction for the pattern, 'N'
|
||||
searches in the opposite direction.
|
||||
|
||||
.TP
|
||||
.B o
|
||||
Open a line below the current line for insertion.
|
||||
|
||||
.TP
|
||||
.B p
|
||||
Put yanked/deleted text back after the cursor. Text is yanked
|
||||
by the delete (d,x,X,D), change (c,C,s,S), and yank (y,Y) commands.
|
||||
|
||||
.TP
|
||||
.B (#)r(x)
|
||||
Replace characters (up to end of line) with (x). '4ra' will change the
|
||||
next 4 characters after the cursor into 'aaaa'.
|
||||
|
||||
.TP
|
||||
.B (#)s
|
||||
change one (count) characters. Shorthand for (#)cl.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)t(x)
|
||||
Move up to a character on the current line. If you are on the first
|
||||
character of the line 'abcdef' and you type 'tf', you will end up sitting
|
||||
on the 'e'.
|
||||
|
||||
.TP
|
||||
.B u
|
||||
Undo last modification. You can undo ANY modification command except
|
||||
:edit, :next, :rm, or :write. (Just like :undo).
|
||||
|
||||
.TP
|
||||
.IB (*) (#)v
|
||||
Move back to the very end of the previous (count'th) word.
|
||||
See 'b' for the definition of a word.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)w
|
||||
Move up to the very beginning of the next (count'th) word.
|
||||
|
||||
.TP
|
||||
.B (#)x
|
||||
Delete one (count) characters forward. Shorthand for (#)dl.
|
||||
|
||||
.TP
|
||||
.B y
|
||||
Yank an object for later use by put. 'yy' yanks whole lines.
|
||||
|
||||
.TP
|
||||
.B A
|
||||
Append text at the end of the line. Shorthand for $a.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)B
|
||||
Move to the beginning of the current word. Exactly like 'b'.
|
||||
|
||||
.B NOTE:
|
||||
this is incorrect. the capitalized word movement commands should,
|
||||
and will in the future, be used for movement by space-delimited words.
|
||||
|
||||
.TP
|
||||
.B C
|
||||
Change to the end of the line. Shorthand for c$.
|
||||
|
||||
.TP
|
||||
.B D
|
||||
Delete to the end of the line. Shorthand for d$.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)F(x)
|
||||
Move to the first (count'th) previous occurance of a character on the
|
||||
current line. If you are sitting at the end of the line 'abcdef', typing
|
||||
"Fa" will move you back to the 'a' at the start of the line.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)G
|
||||
Goto line. If you specify a count, Levee will move to that line, and if
|
||||
there is no count, Levee moves to the absolute end of the file.
|
||||
|
||||
To get to the start of the file, type "1G". To the end, just "G".
|
||||
|
||||
.TP
|
||||
.IB (*) H
|
||||
Move to the first nonwhite character at the top of the screen.
|
||||
|
||||
.TP
|
||||
.B I
|
||||
Insert at the end of the current line. Shorthand for $i.
|
||||
|
||||
.TP
|
||||
.B (#)J
|
||||
Join two (count+1) lines together. Joining appends the second line at
|
||||
the end of the first, putting a space between them. If the first line
|
||||
ends in whitespace, Levee will not put in a space.
|
||||
|
||||
.TP
|
||||
.IB (*) L
|
||||
Move to the last nonwhite character on the last line of the screen.
|
||||
|
||||
.TP
|
||||
.IB (*) M
|
||||
Move to the first nonwhite character in the middle of the screen.
|
||||
|
||||
.TP
|
||||
.B O
|
||||
Open a line above the current line. Otherwise works just like 'o'.
|
||||
|
||||
.TP
|
||||
.B P
|
||||
Put back the yank buffer at the cursor. Otherwise works just like 'p'.
|
||||
|
||||
.TP
|
||||
.B Q
|
||||
Enter and remain in command mode. Just like the command :exec. To get
|
||||
back to visual mode, you must enter the command ':visual'.
|
||||
|
||||
.TP
|
||||
.B R
|
||||
Replace mode. A limited subset of insert mode that overwrites characters
|
||||
up to end of line. All of the normal insert mode commands apply.
|
||||
If you overwrite a character, then back over it with ^H,^U, or ^W, it
|
||||
will reappear after you exit Replace mode.
|
||||
|
||||
Escape exits replace mode.
|
||||
|
||||
.B NOTE:
|
||||
due to a bug, entering a <return> in Replace mode will drop you
|
||||
back into visual mode with an error. The replacements you have made
|
||||
will remain.
|
||||
|
||||
.TP
|
||||
.B S
|
||||
Change characters backwards. Shorthand for (#)ch.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)T(x)
|
||||
Move back to character on current line. If you are on the last character
|
||||
of the line 'abcdef', typing "Ta" will move you back to the 'b'.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)W
|
||||
Move to end of word. Exactly like 'e'.
|
||||
|
||||
.TP
|
||||
.B (#)X
|
||||
Delete characters backwards. Shorthand for (#)dh.
|
||||
|
||||
.TP
|
||||
.B Y
|
||||
Yank to end of line. Shorthand for y$.
|
||||
|
||||
.TP
|
||||
.B ZZ
|
||||
Write changes to current file and exit if last file in arglist.
|
||||
Exactly like :xit.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)$
|
||||
Move to end of line. If you give a count, move to the end of the (count-1)
|
||||
line down (so 2$ moves you to the end of the next line.).
|
||||
|
||||
.TP
|
||||
.B 0
|
||||
Move to the beginning of the current line. Shorthand for 0|.
|
||||
|
||||
.TP
|
||||
.B (#)!
|
||||
Pipe an object through an external program. Like 'cc', '!!' affects whole lines.
|
||||
|
||||
.TP
|
||||
.IB (*) %
|
||||
Find matching bracket, parenthesis, or squiggly bracket. If you are not
|
||||
sitting on a '[]{}()', Levee will search forward for one of them on the
|
||||
current line, then match whatever it finds.
|
||||
|
||||
.TP
|
||||
.B [space]
|
||||
Move to the first nonwhite character on the current line.
|
||||
|
||||
.TP
|
||||
.B &
|
||||
Redo last substitution command.
|
||||
|
||||
.TP
|
||||
.IB (*) (#){
|
||||
Move to the beginning of the count'th paragraph back. A paragraph is
|
||||
delimited by a blank line.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)}
|
||||
Move to the end of the count'th paragraph forward.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)(
|
||||
Move to the beginning of the count'th sentence back. A sentence is
|
||||
delimited by a ., a !, or a ? followed by a space, a tab, or end of line.
|
||||
|
||||
.TP
|
||||
.IB (*) (#))
|
||||
Move to the end of the count'th sentence forward.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)-
|
||||
Move to the (count'th) previous line, first nonwhite.
|
||||
|
||||
.TP
|
||||
.IB (*) (#)+
|
||||
Move to the (count'th) next line, first nonwhite.
|
||||
|
||||
.TP
|
||||
.B (#)~
|
||||
Change the case of the next count characters. Upper case becomes lowercase,
|
||||
lowercase becomes uppercase.
|
||||
|
||||
.TP
|
||||
.IB (*) `(x)
|
||||
Move to the exact position of mark (x). There is a special mark for some
|
||||
of the visual mode move ment commands -- '' will move you to where you
|
||||
were before the last (,),',`,G,/,?,n,N command.
|
||||
|
||||
.TP
|
||||
.B :
|
||||
Execute one command mode command. When the command is done, it will return
|
||||
to visual mode if it produces one line of output, but if it scrolls the
|
||||
screen, Levee will prompt [more] before returning to visual mode. If you
|
||||
type a : in response to the [more] prompt, Levee will remain in command
|
||||
mode for one more command.
|
||||
|
||||
.TP
|
||||
.B (#)<(#)
|
||||
Shift one (count) objects left. If you specify a second count, Levee will
|
||||
shift the object left that many columns -- if you do not, they will be sh
|
||||
shifted shiftwidth columns.
|
||||
|
||||
This is a nondestructive shift. If the shift would carry past the left
|
||||
margin, the objects will be moved up to the left margin but no farther.
|
||||
|
||||
Like the other object movement commands, '<<' will affect whole lines.
|
||||
|
||||
.TP
|
||||
.B (#)>(#)
|
||||
Shift one (count) objects right. Just like <, except it will not shift
|
||||
objects past the right margin of the screen. If you do shift an object
|
||||
past the right margin of the screen, all of its indent will be removed
|
||||
and it will end up by the left margin.
|
||||
|
||||
.TP
|
||||
.B \.
|
||||
Repeat last modification command. (except undo)
|
||||
|
||||
.TP
|
||||
.IB (*) ?
|
||||
Search for pattern backwards. Escape aborts the search pattern, and a
|
||||
empty pattern means search for the last pattern again.
|
||||
|
||||
.TP
|
||||
.IB (*) /
|
||||
Search for pattern forwards. Otherwise like ?.
|
||||
|
||||
.TP
|
||||
.B (#)|
|
||||
Move to specified column. If you don't have a count, move to column 0.
|
||||
|
||||
.SH "REGULAR EXPRESSIONS"
|
||||
|
||||
Levee gives special meanings to some characters during
|
||||
a pattern match. The character "." will match any one char,
|
||||
the character "*" will match zero or more occurances of the
|
||||
previous char ( so, a* will match 'a','aa','aaa', etc, or it
|
||||
will match nothing at all). If a pattern begins with "^", it
|
||||
will only match at the beginning of a line, and patterns
|
||||
ending with a "$" will only match at the end of a line.
|
||||
|
||||
Brackets ('[]') have special meaning as well. They mean
|
||||
match any one of the characters inside the brackets. '[abc]'
|
||||
will match 'a', 'b', or 'c'. You may specify a range of
|
||||
characters inside brackets by using a dash (-). '[a-z]' will
|
||||
match any lowercase alphabetic character. If ^ is the first
|
||||
character in the bracket, it means match any character
|
||||
except those in the brackets. '[^abc]' will match anything
|
||||
except 'a','b', or 'c'.
|
||||
|
||||
Backslash takes away special meaning for these chars,
|
||||
but '\\t' specifies a tab, and \\( & \\) delimit arguments
|
||||
inside a pattern (used only by :substitute.) The patterns
|
||||
\\< and \\> have special meaning, too; they match the start
|
||||
and end of alpha-numeric tokens.
|
||||
|
||||
If you turn off the editor variable 'magic', none of
|
||||
the above characters will have special meaning inside of
|
||||
a pattern (see 'set').
|
||||
|
||||
Some example patterns:
|
||||
|
||||
.TP
|
||||
.B ^end$
|
||||
Find a line that is just 'end'.
|
||||
.TP
|
||||
.B [Ee][Nn][Dd]
|
||||
Find a 'end', ignoring case.
|
||||
.TP
|
||||
.B [A-Za-z][A-Za-z0-9]*
|
||||
Find the next identifier.
|
||||
.TP
|
||||
.B (\\*.*\\*)
|
||||
Find the next one-line pascal comment.
|
||||
.TP
|
||||
.B \<the\>
|
||||
Find the next occurance of `the'.
|
||||
|
||||
|
||||
.SH LIMITATIONS
|
||||
Levee can only edit files up to 256000 characters long. ^M is used
|
||||
as its internal line separator, so inserting ^M will have interesting
|
||||
consequences.
|
||||
|
||||
.SH BUGS
|
||||
Probably infinite.
|
||||
|
||||
.SH AUTHOR
|
||||
.B "David L. Parsons"
|
||||
.I (orc@pell.chi.il.us)
|
||||
.br
|
||||
Testing, suggestions, and impractical design goals by:
|
||||
Jim Bolland. John Tainter. John Plocher.
|
||||
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 1982-2007 David L Parsons
|
||||
.br
|
||||
All rights reserved.
|
||||
.br
|
||||
|
||||
Redistribution and use in source and binary forms, without or
|
||||
without modification, are permitted provided that the above
|
||||
copyright notice and this paragraph are duplicated in all such
|
||||
forms and that any documentation, advertising materials, and
|
||||
other materials related to such distribution and use acknowledge
|
||||
that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
My name may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE.
|
||||
873
src/cmd/levee/lv.doc
Normal file
873
src/cmd/levee/lv.doc
Normal file
@@ -0,0 +1,873 @@
|
||||
Levee. A Screen Oriented Editor.
|
||||
|
||||
USAGE
|
||||
lv [+address] [file ...]
|
||||
|
||||
SYNOPSIS
|
||||
Levee is a screen oriented editor based on the Unix editor
|
||||
"vi". It provides a terse, powerful way to enter and edit text
|
||||
(however, if you want a word-processor, you're better off with
|
||||
WordStar.)
|
||||
|
||||
DESCRIPTION
|
||||
Levee is a moded editor. It operates in 3 modes -- visual,
|
||||
command, and insert. Most of the editing work is done is visual
|
||||
mode, file reading and writing is done in command mode, and
|
||||
insert mode does what you would expect.
|
||||
When you enter Levee, you may specify an address to start
|
||||
editing at. These addresses are in the same format as command
|
||||
mode addresses, except that a naked + will put you at the very
|
||||
end of the file.
|
||||
|
||||
Levee is copyright (c) 1982-1997 by David L. Parsons. (see
|
||||
the notice at the end of this document for distribution terms)
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
COMMANDS
|
||||
|
||||
Command mode commands:
|
||||
|
||||
These commands are used for editing new files, writing
|
||||
modified files, changing options, doing substitutions, and
|
||||
a subset of the visual commands. They take as input whole
|
||||
lines, terminated by return (to execute), or escape (to
|
||||
abort.)
|
||||
|
||||
Command mode is reached by typing ":" or "Q" from visual
|
||||
mode. If you enter command mode by typing ":", Levee will
|
||||
execute one command, then return to visual mode after
|
||||
prompting you with "[more]". If you type anything except
|
||||
a space or return, Levee will accept another command, and so
|
||||
forth. If, however, you enter command mode via "Q", Levee
|
||||
will remain in command mode until you enter the "visual"
|
||||
command.
|
||||
|
||||
A NOTE ON COMMAND SYNTAX
|
||||
A command may be preceded by an optional line-range. If
|
||||
you do not provide a line-range, Levee will use the default
|
||||
line-range shown by the command. A line-range is one or two
|
||||
address specifications in the following format:
|
||||
|
||||
(.|$|'x|#) [ (+|-) (/patt/|?patt?|#) ]
|
||||
|
||||
. => current line.
|
||||
$ => last line.
|
||||
'x => the line with mark x on it.
|
||||
# => line #.
|
||||
|
||||
For example, ".-5,.+5p" will print every line within ten
|
||||
lines of the current line. "$-5" is the fifth line from the
|
||||
end of the file, and "/end/+2" is the second line past the
|
||||
next occurrence of the pattern "end". Patterns may be
|
||||
regular expressions (see below.)
|
||||
|
||||
Also, a naked line-range will set the current line to
|
||||
the first line in the range and print all the lines in that
|
||||
range. "1,10" sets the current line to 1, then prints lines
|
||||
1 to 10.
|
||||
|
||||
If you specify a non-existent line in a range, the comm-
|
||||
and will abort and Levee will tell you "bad address".
|
||||
|
||||
Regular expressions:
|
||||
Levee gives special meanings to some characters during
|
||||
a pattern match. The character "." will match any one char,
|
||||
the character "*" will match zero or more occurances of the
|
||||
previous char ( so, a* will match 'a','aa','aaa', etc, or it
|
||||
will match nothing at all). If a pattern begins with "^", it
|
||||
will only match at the beginning of a line, and patterns
|
||||
ending with a "$" will only match at the end of a line.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
Brackets ('[]') have special meaning as well. They mean
|
||||
match any one of the characters inside the brackets. '[abc]'
|
||||
will match 'a', 'b', or 'c'. You may specify a range of
|
||||
characters inside brackets by using a dash (-). '[a-z]' will
|
||||
match any lowercase alphabetic character. If ^ is the first
|
||||
character in the bracket, it means match any character
|
||||
except those in the brackets. '[^abc]' will match anything
|
||||
except 'a','b', or 'c'.
|
||||
|
||||
Backslash takes away special meaning for these chars,
|
||||
but '\t' specifies a tab, and \( & \) delimit arguments
|
||||
inside a pattern (used only by :substitute.) The patterns
|
||||
\< and \> have special meaning, too; they match the start
|
||||
and end of alpha-numeric tokens.
|
||||
|
||||
If you turn off the editor variable 'magic', none of
|
||||
the above characters will have special meaning inside of
|
||||
a pattern (see 'set').
|
||||
|
||||
Some example patterns:
|
||||
|
||||
^end$ Find a line that is just 'end'.
|
||||
[Ee][Nn][Dd] Find a 'end', ignoring case.
|
||||
[A-Za-z][A-Za-z0-9]* Find the next identifier.
|
||||
(\*.*\*) Find the next one-line pascal
|
||||
comment.
|
||||
\<the\> Find the next occurance of `the'.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
|
||||
---------------
|
||||
args
|
||||
show the current argument list, if one exists. The file that you
|
||||
are currently editing will be framed by '[' and ']'.
|
||||
|
||||
---------------
|
||||
(.,.) change
|
||||
delete lines, then enter insert mode.
|
||||
|
||||
---------------
|
||||
(.,.) delete
|
||||
delete lines. Deleted lines are stored in a Yank Buffer for
|
||||
later putback with "put".
|
||||
|
||||
---------------
|
||||
edit[!] [file]
|
||||
Discard the current file and start editing a new one. If
|
||||
changes were made to the current file, you must enter "edit!"
|
||||
to force Levee to discard the changes. If you do not specify
|
||||
a filename, Levee will try to reedit the current filename.
|
||||
|
||||
When Levee reads in a new file, it will tell you how many
|
||||
bytes it read in, or [overflow] if the file is larger than the
|
||||
internal buffer (currently 32760 bytes.)
|
||||
|
||||
---------------
|
||||
execmode
|
||||
Remain in command mode until you use the "visual" command.
|
||||
|
||||
---------------
|
||||
file [name]
|
||||
Echo what the current filename is, its status, and the current
|
||||
line. If you provide it with a name, it will change the filename
|
||||
to that.
|
||||
|
||||
---------------
|
||||
(.) insert
|
||||
Insert text above the current line. If you specify a line number,
|
||||
Levee will make that the current line, then insert above it.
|
||||
|
||||
Commands within insert mode:
|
||||
^W => back over the last word you entered.
|
||||
^H => back over one character.
|
||||
^U => back over all input on this line.
|
||||
^V => escape the next character typed.
|
||||
^V^H will put a ^H into the file.
|
||||
ESC => exit insert mode.
|
||||
^D => If at start of line, reduce indentation 'shiftwidth'
|
||||
columns.
|
||||
^T => If at start of line, increase indentation
|
||||
'shiftwidth' columns.
|
||||
|
||||
When in insert mode, Levee will not allow you to enter any control
|
||||
characters except return and tab. Return ends input on this line and
|
||||
opens a new line for input.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
map[!] [key [text]]
|
||||
Define/list macros. There are 3 forms of map:
|
||||
|
||||
1) map. This lists all the active macros.
|
||||
2) map (key). This shows the macro associated with (key),
|
||||
if any.
|
||||
3) map (key) (text)
|
||||
This maps (key) to (text). You may map any
|
||||
key except ":" and escape. In the normal
|
||||
form (map), the macro will be effective
|
||||
in visual mode, but in the alternate form,
|
||||
(map!), the macro will be effective in
|
||||
insert and command modes.
|
||||
|
||||
For example, if you map!ped return to "hello world", every time
|
||||
you entered a return in command or visual mode, the string "hello
|
||||
world" would pop up.
|
||||
|
||||
---------------
|
||||
next [file ...]
|
||||
Edit the next file in the arglist, or edit a new arglist. Levee
|
||||
takes its initial arglist off the command line when you execute it.
|
||||
If "autowrite" is set, Levee will write out the changes to the
|
||||
current file before editing the next one.
|
||||
|
||||
---------------
|
||||
(.) open
|
||||
Insert below the current line. Otherwise just like insert.
|
||||
|
||||
---------------
|
||||
previous
|
||||
Edit the previous file in the arglist. Otherwise, like next.
|
||||
|
||||
---------------
|
||||
(.,.) print
|
||||
Display lines without changing the current line.
|
||||
|
||||
---------------
|
||||
(.) put
|
||||
Put the contents of the yank buffer back on the line below
|
||||
the current line. If you specify a line, it resets the current
|
||||
line, then puts the yank buffer back. The yank buffer is filled
|
||||
by the delete, change, or yank commands. Put does not destroy
|
||||
the yank buffer, so you may put back text multiple times.
|
||||
|
||||
---------------
|
||||
quit[!]
|
||||
Exit Levee. If you want to discard changes, use "quit!"
|
||||
|
||||
---------------
|
||||
(.) read [file]
|
||||
put the contents of 'file' after the current line.
|
||||
|
||||
---------------
|
||||
rm file
|
||||
Delete 'file' from disk.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
set [option=value]
|
||||
Set a tunable variable. Levee has a dozen or so user-definable
|
||||
variables which you can twiddle via this command. There are boolean,
|
||||
integer, and string variables that you can set. A string or integer
|
||||
variable is set by 'set xxx=yyy', a boolean variable is set via
|
||||
'set xxx' or 'set noxxx'.
|
||||
|
||||
Here are the settable variables (and abbreviations):
|
||||
tabsize (ts) tab stop.
|
||||
shiftwidth (sw) columns to shift on ^D, ^T, >>, or <<
|
||||
scroll number of lines to scroll on ^D, ^U
|
||||
autoindent (ai) supply indentation during insert mode.
|
||||
autowrite (aw) write out changes before :next, :prev
|
||||
autocopy (ac) make backup copies of before writing.
|
||||
list display tabs as ^I, end of line as $.
|
||||
magic use regular expressions in searches.
|
||||
suffix if the filename does not have a . in
|
||||
it, supply the suffix. (this is the
|
||||
only string variable.)
|
||||
overwrite (ow) destroy old file first, then write.
|
||||
beautify (be) When set, Levee will not allow insert
|
||||
of any control character except tab
|
||||
and return unless you escape it with
|
||||
ctrl-V.
|
||||
wrapscan searches wrap around end of buffer.
|
||||
ignorecase (ic) Ignore the case of alphabetic characters
|
||||
during searches.
|
||||
mapslash (ST version only) Map '/' in filenames to
|
||||
'\'. If the environment contains `mapslash'
|
||||
when levee is called, this variable will
|
||||
default to true, otherwise it defaults to
|
||||
false. (See the documentation for the
|
||||
Teeny-shell on how the teeny-shell interprets
|
||||
`mapslash')
|
||||
lines (li) (ST version only) How many lines on the display.
|
||||
This is primarily for running levee through
|
||||
the serial port - put set li=xx into your
|
||||
LVRC for a xx line terminal.
|
||||
cols (co) (ST version only) How many columns on the
|
||||
display. Like the lines variable, it's for
|
||||
running levee through the serial port.
|
||||
|
||||
You may set multiple variables on one line, as in 'set ws noai'.
|
||||
To see the current settings of these variables, :set -- without any
|
||||
arguments -- will show the current settings.
|
||||
|
||||
At startup, Levee looks in the environment variable LVRC for
|
||||
a list of variables to set (GEMDOS/MS-DOS). LVRC is one line
|
||||
of the form 'option=value ...'. If you have a LVRC defined that
|
||||
is 'ts=4 ow nows', Levee will set tabsize to 4, turn on overwrite,
|
||||
and turn off wrapscan.
|
||||
|
||||
If you are using RMX, Levee looks in the file ":home:r?lvrc"
|
||||
for initialization. If you are using Osy/SWOs, Levee looks in the
|
||||
file "*.lvrc". The format of these files are different from the
|
||||
LVRC variable -- see "source" for more information.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
source file
|
||||
Take command mode commands from 'file'. These commands can be
|
||||
any legal command, except "visual". If a error happens during
|
||||
execution of 'file', Levee abandons that level of source'ing.
|
||||
|
||||
In Osy/SWOs, there are a few differences in insert mode from
|
||||
within a sourced file. No character has special meaning except a
|
||||
line containing nothing but a period, which terminates insert mode.
|
||||
For example:
|
||||
|
||||
:commands
|
||||
.
|
||||
.
|
||||
:insert
|
||||
blah blah blah blah blah blah
|
||||
blah blah blah blah blah blah
|
||||
blah blah blah blah blah blah
|
||||
.
|
||||
:more commands
|
||||
|
||||
If you are running Levee under any other operating system,
|
||||
you cannot do a insert from a :source file.
|
||||
|
||||
NOTE: If you are running Levee on RMX or Osy/SWOs, it will read
|
||||
":home:r?lvrc" or "*.lvrc" at startup. These can consist of any
|
||||
legal command mode instruction, just like any other source file.
|
||||
|
||||
---------------
|
||||
(.,.)substitute(delim)patt(delim)repl(delim)[qcpg]
|
||||
(.,.)substitute&
|
||||
Search for patt and replace it with repl. Levee will look for
|
||||
patt once on each line and replace it with repl. The delimiter
|
||||
may be any ascii character.
|
||||
|
||||
The pattern is a regular expression, just like a search
|
||||
pattern.
|
||||
|
||||
You may include parts of the pattern in the replacement string;
|
||||
A '&' in the replacement pattern copies in the whole source pattern,
|
||||
so if you do a 'sub/this/& and that/g', every instance of 'this'
|
||||
will be replaced with 'this and that'. Also, you may pull parts of
|
||||
the pattern out by using the \( and \) argument meta-characters.
|
||||
Arguments gotten by \( & \) are put into the replacement string
|
||||
everywhere you do a \1..\9 [ \1 is the first argument you set up
|
||||
with \( & \) ]. So, if you want to reverse the order of two substrings,
|
||||
you can do 'sub/\(string1\)\(string2\)/\2\1/'.
|
||||
|
||||
substitute& redoes the last substitution.
|
||||
|
||||
Options:
|
||||
q,c => before doing the substitute, display the affected
|
||||
line and wait for you to type a character. If you
|
||||
type 'y', it will do the substitution. 'q' aborts
|
||||
the substitute, 'a' does the rest of the change
|
||||
without prompting, and 'n' does not do it.
|
||||
p => print the affected lines after the change.
|
||||
g => do the change globally. That is, do it for every
|
||||
occurence of patt on a line, rather than just
|
||||
once.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
undo
|
||||
Undo the last modification to the file (except :edit, :next, :rm,
|
||||
or :write.) You can only undo the last change to a file -- undo counts
|
||||
as a change. :undo followed by :undo does nothing to the file.
|
||||
|
||||
---------------
|
||||
unmap (key)
|
||||
Undefine a macro (see map).
|
||||
|
||||
---------------
|
||||
visual [list]
|
||||
If you entered command mode by "Q" or "execmode", return to
|
||||
visual mode. If you provide an argument list, it also does a
|
||||
`:next' on that list.
|
||||
|
||||
---------------
|
||||
version
|
||||
Show which version of levee this is.
|
||||
|
||||
---------------
|
||||
(.,.) write [file]
|
||||
Write lines to a file. If you write the everything to 'file',
|
||||
the filename is set to 'file', and if you do not specify a file,
|
||||
Levee will write to the filename.
|
||||
|
||||
---------------
|
||||
(.,.) wq [file]
|
||||
Write to a file, then quit.
|
||||
|
||||
---------------
|
||||
(.,.) yank
|
||||
Yank lines from the file into the yank buffer, for later
|
||||
putback with "put".
|
||||
|
||||
---------------
|
||||
xit[!]
|
||||
Write changes to the current file, then exit. If there are
|
||||
more files in the arglist, use "xit!"
|
||||
|
||||
---------------
|
||||
![command]
|
||||
Execute command.
|
||||
|
||||
Example:
|
||||
!ls => does a 'ls'.
|
||||
|
||||
This command is available only under GEMDOS, MSDOS, and RMX.
|
||||
|
||||
---------------
|
||||
($)=
|
||||
Give the line number of the addressed line. /end/= gives you
|
||||
the line number of the next line with a 'end' on it.
|
||||
|
||||
---------------
|
||||
Levee. A Screen Oriented Editor.
|
||||
Visual mode commands.
|
||||
Visual mode commands move you around and modify the file.
|
||||
There are movement commands to move the cursor by a variety of
|
||||
objects.
|
||||
|
||||
In the description, a (#) means a optional count. If a
|
||||
command has a optional count, it will tell you what the count
|
||||
does in parenthesis. A (*) means that the command can be used
|
||||
in the delete, yank, and change commands.
|
||||
|
||||
Counts are made up by entering digits. If you type '45',
|
||||
the count will be set to 45. To cancel a count, type ESC.
|
||||
|
||||
This section discusses 'whitespace' occasionally.
|
||||
Whitespace is tabs, spaces, and end of line.
|
||||
|
||||
How the display works.
|
||||
|
||||
Characters are displayed on the screen as you would
|
||||
expect, except that nonprinting characters are shown as ^x,
|
||||
and tabs expand to spaces ( unless you set the option list,
|
||||
then they show as ^I.) When sitting on a control character or
|
||||
tab, the cursor is placed on the FIRST character displayed. If
|
||||
you move the cursor to any other part of them ( via j or k --
|
||||
see below), any changes will start at the next character.
|
||||
|
||||
Levee does not display a end of file marker, but lines
|
||||
past the end of the file are denoted by ~ lines.
|
||||
|
||||
If list is set, tabs display as ^I, and the end of line
|
||||
displays as $.
|
||||
|
||||
If a line is too long for the screen, it will just dis-
|
||||
appear off the end of the screen.
|
||||
|
||||
Levee will handle any screen resolution and any monospaced
|
||||
font you hand it ( if you are running in low resolution, Levee
|
||||
will give you a 25x40 window, for example.)
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
^A
|
||||
Show a debugging message at the bottom of the screen. This is not at
|
||||
all useful unless you are debugging the editor. Ignore it.
|
||||
|
||||
---------------
|
||||
(#)^D
|
||||
Scroll the screen down a half screen. If a count is specified, scroll
|
||||
down the specified number of lines.
|
||||
|
||||
---------------
|
||||
^E
|
||||
Scroll down 1 line (shorthand for 1^D )
|
||||
|
||||
---------------
|
||||
^G
|
||||
Show file statistics. Exactly like ':file'.
|
||||
|
||||
(*)------------
|
||||
(#)^H
|
||||
Move the cursor left one (count) chars.
|
||||
|
||||
---------------
|
||||
^I
|
||||
Redraw the screen.
|
||||
|
||||
(*)------------
|
||||
(#)^J
|
||||
Move down one (count) lines. When you use ^J and ^K (below) to move
|
||||
up or down lines, the cursor will remain in the same column, even if
|
||||
it is in the middle of a tabstop or past the end of a line.
|
||||
|
||||
(*)------------
|
||||
(#)^K
|
||||
Move up one (count) lines.
|
||||
|
||||
(*)------------
|
||||
(#)^L
|
||||
Move right one (count) characters.
|
||||
|
||||
(*)------------
|
||||
(#)^M
|
||||
Move to the first nonwhite space on the next line. If a count is specified,
|
||||
move to the first nonwhite count lines down.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
(#)^U
|
||||
Scroll the screen up a half page. If a count is specified, scroll up
|
||||
count lines.
|
||||
|
||||
---------------
|
||||
^Y
|
||||
Scroll the screen up 1 line (shorthand for 1^U.)
|
||||
|
||||
---------------
|
||||
(#)a
|
||||
Insert text AFTER the cursor. If you give a count, the insertion will
|
||||
be repeated count times ( 40i-ESC will give you a line of 40 dashes).
|
||||
|
||||
The commands in insert mode are the same for visual and command mode.
|
||||
|
||||
(*)------------
|
||||
(#)b
|
||||
Move to the beginning of the last word (the count'th word back).
|
||||
A word is a collection of alphanumeric characters (a-z0-9$_#) or
|
||||
any other nonwhite character (i.e. anything but space, tab, eoln).
|
||||
|
||||
---------------
|
||||
c
|
||||
Change a object. Change deletes an object, then enters insert mode without
|
||||
redrawing the screen. When you tell it the object to be changed, Levee
|
||||
puts a '$' on the last character of the object. You cannot change
|
||||
backwards.
|
||||
|
||||
The object may be any visual mode command marked with a '(*)'. For
|
||||
example, 'c4l' will change the next 4 characters on the line to something
|
||||
else. (4cl does the same thing -- 4c4l changes the next 16 characters on
|
||||
this line.)
|
||||
|
||||
'cc' will change whole lines.
|
||||
|
||||
When changing, deleting, or yanking a object, it will be placed into
|
||||
a yank buffer, where it can be retrieved by the 'p' or 'P' commands.
|
||||
|
||||
---------------
|
||||
(#)d
|
||||
Delete an object. Like 'cc', 'dd' effects whole lines.
|
||||
|
||||
(*)------------
|
||||
(#)e
|
||||
Move to the end of the current word.
|
||||
|
||||
(*)------------
|
||||
(#)f(x)
|
||||
Find the next (count'th) occurance of a character on the current line.
|
||||
For example, if the cursor is sitting on the first character of the
|
||||
line 'abcdef', typing "ff" will put the cursor on the 'f'.
|
||||
|
||||
(*)------------
|
||||
(#)h
|
||||
Move left one (count) characters. Exactly like ^H.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
(#)i
|
||||
Start inserting characters at the cursor. If you specify a count,
|
||||
the insertion will be duplicated count times.
|
||||
|
||||
(*)------------
|
||||
(#)j
|
||||
Move down one (count) lines. Exactly like ^J.
|
||||
|
||||
(*)------------
|
||||
(#)k
|
||||
Move up one (count) lines. Exactly like ^K.
|
||||
|
||||
(*)------------
|
||||
(#)l
|
||||
Move right one (count) character. Exactly like ^L.
|
||||
|
||||
---------------
|
||||
m(x)
|
||||
Set the marker (x). There are 26 markers available (a-z). You may
|
||||
move to a marker by use of the ' or ` commands.
|
||||
|
||||
(*)------------
|
||||
n
|
||||
Find the next occurance of a search pattern. When you do a search with
|
||||
a / or ? command, Levee will remember the pattern and the direction you
|
||||
searched in. 'n' will search in the same direction for the pattern, 'N'
|
||||
searches in the opposite direction.
|
||||
|
||||
---------------
|
||||
o
|
||||
Open a line below the current line for insertion.
|
||||
|
||||
---------------
|
||||
p
|
||||
Put yanked/deleted text back after the cursor. Text is yanked
|
||||
by the delete (d,x,X,D), change (c,C,s,S), and yank (y,Y) commands.
|
||||
|
||||
---------------
|
||||
(#)r(x)
|
||||
Replace characters (up to end of line) with (x). '4ra' will change the
|
||||
next 4 characters after the cursor into 'aaaa'.
|
||||
|
||||
---------------
|
||||
(#)s
|
||||
change one (count) characters. Shorthand for (#)cl.
|
||||
|
||||
(*)------------
|
||||
(#)t(x)
|
||||
Move up to a character on the current line. If you are on the first
|
||||
character of the line 'abcdef' and you type 'tf', you will end up sitting
|
||||
on the 'e'.
|
||||
|
||||
---------------
|
||||
u
|
||||
Undo last modification. You can undo ANY modification command except
|
||||
:edit, :next, :rm, or :write. (Just like :undo).
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
(*)------------
|
||||
(#)v
|
||||
Move back to the very end of the previous (count'th) word.
|
||||
See 'b' for the definition of a word.
|
||||
|
||||
(*)------------
|
||||
(#)w
|
||||
Move up to the very beginning of the next (count'th) word.
|
||||
|
||||
---------------
|
||||
(#)x
|
||||
Delete one (count) characters forward. Shorthand for (#)dl.
|
||||
|
||||
---------------
|
||||
y
|
||||
Yank an object for later use by put. 'yy' yanks whole lines.
|
||||
|
||||
---------------
|
||||
A
|
||||
Append text at the end of the line. Shorthand for $a.
|
||||
|
||||
(*)------------
|
||||
(#)B
|
||||
Move to the beginning of the current word. Exactly like 'b'.
|
||||
|
||||
NOTE: this is incorrect. the capitalized word movement commands should,
|
||||
and will in the future, be used for movement by space-delimited words.
|
||||
|
||||
---------------
|
||||
C
|
||||
Change to the end of the line. Shorthand for c$.
|
||||
|
||||
---------------
|
||||
D
|
||||
Delete to the end of the line. Shorthand for d$.
|
||||
|
||||
(*)------------
|
||||
(#)F(x)
|
||||
Move to the first (count'th) previous occurance of a character on the
|
||||
current line. If you are sitting at the end of the line 'abcdef', typing
|
||||
"Fa" will move you back to the 'a' at the start of the line.
|
||||
|
||||
(*)------------
|
||||
(#)G
|
||||
Goto line. If you specify a count, Levee will move to that line, and if
|
||||
there is no count, Levee moves to the absolute end of the file.
|
||||
|
||||
To get to the start of the file, type "1G". To the end, just "G".
|
||||
|
||||
(*)------------
|
||||
H
|
||||
Move to the first nonwhite character at the top of the screen.
|
||||
|
||||
---------------
|
||||
I
|
||||
Insert at the end of the current line. Shorthand for $i.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
(#)J
|
||||
Join two (count+1) lines together. Joining appends the second line at
|
||||
the end of the first, putting a space between them. If the first line
|
||||
ends in whitespace, Levee will not put in a space.
|
||||
|
||||
(*)------------
|
||||
L
|
||||
Move to the last nonwhite character on the last line of the screen.
|
||||
|
||||
(*)------------
|
||||
M
|
||||
Move to the first nonwhite character in the middle of the screen.
|
||||
|
||||
---------------
|
||||
O
|
||||
Open a line above the current line. Otherwise works just like 'o'.
|
||||
|
||||
---------------
|
||||
P
|
||||
Put back the yank buffer at the cursor. Otherwise works just like 'p'.
|
||||
|
||||
---------------
|
||||
Q
|
||||
Enter and remain in command mode. Just like the command :exec. To get
|
||||
back to visual mode, you must enter the command ':visual'.
|
||||
|
||||
---------------
|
||||
R
|
||||
Replace mode. A limited subset of insert mode that overwrites characters
|
||||
up to end of line. All of the normal insert mode commands apply.
|
||||
If you overwrite a character, then back over it with ^H,^U, or ^W, it
|
||||
will reappear after you exit Replace mode.
|
||||
|
||||
Escape exits replace mode.
|
||||
|
||||
NOTE: due to a bug, entering a <return> in Replace mode will drop you
|
||||
back into visual mode with an error. The replacements you have made
|
||||
will remain.
|
||||
|
||||
---------------
|
||||
S
|
||||
Change characters backwards. Shorthand for (#)ch.
|
||||
|
||||
(*)------------
|
||||
(#)T(x)
|
||||
Move back to character on current line. If you are on the last character
|
||||
of the line 'abcdef', typing "Ta" will move you back to the 'b'.
|
||||
|
||||
(*)------------
|
||||
(#)W
|
||||
Move to end of word. Exactly like 'e'.
|
||||
|
||||
---------------
|
||||
(#)X
|
||||
Delete characters backwards. Shorthand for (#)dh.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
---------------
|
||||
Y
|
||||
Yank to end of line. Shorthand for y$.
|
||||
|
||||
---------------
|
||||
ZZ
|
||||
Write changes to current file and exit if last file in arglist.
|
||||
Exactly like :xit.
|
||||
|
||||
(*)------------
|
||||
(#)$
|
||||
Move to end of line. If you give a count, move to the end of the (count-1)
|
||||
line down (so 2$ moves you to the end of the next line.).
|
||||
|
||||
(*)------------
|
||||
%
|
||||
Find matching bracket, parenthesis, or squiggly bracket. If you are not
|
||||
sitting on a '[]{}()', Levee will search forward for one of them on the
|
||||
current line, then match whatever it finds.
|
||||
|
||||
(*)------------
|
||||
^
|
||||
Move to the first nonwhite character on the current line.
|
||||
|
||||
(*)------------
|
||||
&
|
||||
Redo last substitution command.
|
||||
|
||||
(*)------------
|
||||
(#){
|
||||
Move to the beginning of the count'th paragraph back. A paragraph is
|
||||
delimited by a blank line.
|
||||
|
||||
(*)------------
|
||||
(#)}
|
||||
Move to the end of the count'th paragraph forward.
|
||||
|
||||
(*)------------
|
||||
(#)(
|
||||
Move to the beginning of the count'th sentence back. A sentence is
|
||||
delimited by a ., a !, or a ? followed by a space, a tab, or end of line.
|
||||
|
||||
(*)------------
|
||||
(#))
|
||||
Move to the end of the count'th sentence forward.
|
||||
|
||||
(*)------------
|
||||
(#)-
|
||||
Move to the (count'th) previous line, first nonwhite.
|
||||
|
||||
(*)------------
|
||||
(#)+
|
||||
Move to the (count'th) next line, first nonwhite.
|
||||
|
||||
---------------
|
||||
(#)~
|
||||
Change the case of the next count characters. Upper case becomes lowercase,
|
||||
lowercase becomes uppercase.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
(*)------------
|
||||
`(x)
|
||||
Move to the exact position of mark (x). There is a special mark for some
|
||||
of the visual mode move ment commands -- '' will move you to where you
|
||||
were before the last (,),',`,G,/,?,n,N command.
|
||||
|
||||
---------------
|
||||
:
|
||||
Execute one command mode command. When the command is done, it will return
|
||||
to visual mode if it produces one line of output, but if it scrolls the
|
||||
screen, Levee will prompt [more] before returning to visual mode. If you
|
||||
type a : in response to the [more] prompt, Levee will remain in command
|
||||
mode for one more command.
|
||||
|
||||
---------------
|
||||
(#)<(#)
|
||||
Shift one (count) objects left. If you specify a second count, Levee will
|
||||
shift the object left that many columns -- if you do not, they will be sh
|
||||
shifted shiftwidth columns.
|
||||
|
||||
This is a nondestructive shift. If the shift would carry past the left
|
||||
margin, the objects will be moved up to the left margin but no farther.
|
||||
|
||||
Like the other object movement commands, '<<' will affect whole lines.
|
||||
|
||||
---------------
|
||||
(#)>(#)
|
||||
Shift one (count) objects right. Just like <, except it will not shift
|
||||
objects past the right margin of the screen. If you do shift an object
|
||||
past the right margin of the screen, all of its indent will be removed
|
||||
and it will end up by the left margin.
|
||||
|
||||
---------------
|
||||
.
|
||||
Repeat last modification command. (except undo)
|
||||
|
||||
(*)------------
|
||||
?
|
||||
Search for pattern backwards. Escape aborts the search pattern, and a
|
||||
empty pattern means search for the last pattern again.
|
||||
|
||||
(*)------------
|
||||
/
|
||||
Search for pattern forwards. Otherwise like ?.
|
||||
|
||||
(*)------------
|
||||
(#)|
|
||||
Move to specified column. If you don't have a count, move to column 0.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
Levee can only edit files up to 256000 characters long. ^M is used
|
||||
as its internal line separator, so inserting ^M will have interesting
|
||||
consequences.
|
||||
|
||||
BUGS
|
||||
Probably infinite.
|
||||
|
||||
AUTHOR
|
||||
David L. Parsons (orc)
|
||||
|
||||
Testing, suggestions, and impractical design goals by:
|
||||
Jim Bolland.
|
||||
John Tainter.
|
||||
John Plocher.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
Copyright (c) 1982-2007 David L Parsons
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms are permitted
|
||||
provided that the above copyright notice and this paragraph are
|
||||
duplicated in all such forms and that any documentation,
|
||||
advertising materials, and other materials related to such
|
||||
distribution and use acknowledge that the software was developed
|
||||
by David L Parsons (orc@pell.chi.il.us). My name may not be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission. THIS SOFTWARE IS PROVIDED
|
||||
AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Levee. A Screen Oriented Editor.
|
||||
I N D E X
|
||||
Are you kidding?
|
||||
313
src/cmd/levee/main.c
Normal file
313
src/cmd/levee/main.c
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if OS_RMX
|
||||
extern alien token rq$get$task$tokens(); /* for unique files */
|
||||
#endif
|
||||
|
||||
VOID PROC
|
||||
stamp(s, template)
|
||||
/* make a unique temporary file */
|
||||
char *s;
|
||||
char *template;
|
||||
{
|
||||
#if OS_RMX
|
||||
token dummy;
|
||||
|
||||
strcpy(s, ":work:");
|
||||
strcat(s, template);
|
||||
numtoa(&s[strlen(s)], rq$get$task$tokens(0,&dummy));
|
||||
#else
|
||||
#if OS_DOS || OS_ATARI
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
#if OS_UNIX
|
||||
strcpy(s, "/tmp/");
|
||||
#endif
|
||||
|
||||
#if OS_FLEXOS
|
||||
s[0] = 0;
|
||||
#endif
|
||||
|
||||
#if OS_DOS
|
||||
if (p=getenv("TMP")) {
|
||||
strcpy(s, p);
|
||||
if (s[strlen(s)-1] != '\\')
|
||||
strcat(s, "\\");
|
||||
}
|
||||
else
|
||||
s[0] = 0;
|
||||
#endif
|
||||
#if OS_ATARI
|
||||
if (p=getenv("_TMP")) {
|
||||
strcpy(s, p);
|
||||
if (s[strlen(s)-1] != '\\')
|
||||
strcat(s, "\\");
|
||||
}
|
||||
else
|
||||
s[0] = 0;
|
||||
#endif
|
||||
strcat(s, template);
|
||||
numtoa(&s[strlen(s)], getpid());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if OS_RMX|OS_UNIX
|
||||
PROC void
|
||||
ctrlc()
|
||||
/* ctrlc: RMX control-C handler */
|
||||
{
|
||||
count = 0; /* clear count, eh? */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_RMX
|
||||
PROC
|
||||
settty()
|
||||
/* settty: set up the terminal for raw input */
|
||||
{
|
||||
unsigned dummy;
|
||||
/* transparent mode? */
|
||||
dq$special(1,&fileno(stdin),&dummy);
|
||||
|
||||
/* turn off control character assignments */
|
||||
strput("\033]T:C15=0,C18=0,C20=0,C21=0,C23=0\033\\");
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID PROC
|
||||
initialize(count, args)
|
||||
int count;
|
||||
char **args;
|
||||
/* initialize: set up everything I can in levee */
|
||||
{
|
||||
int i;
|
||||
#if OS_RMX
|
||||
int xmode = E_INIT, xquit;
|
||||
#else
|
||||
char *getenv();
|
||||
#if OS_ATARI
|
||||
extern int mapslash;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OS_UNIX
|
||||
signal(SIGINT, ctrlc);
|
||||
#else
|
||||
signal(SIGINT, SIG_IGN);
|
||||
#endif
|
||||
initcon();
|
||||
|
||||
#if OS_RMX
|
||||
exception(0);
|
||||
dq$trap$cc(ctrlc,&i);
|
||||
#endif
|
||||
|
||||
#if TTY_ZTERM
|
||||
zconfig();
|
||||
#endif /*TTY_ZTERM*/
|
||||
|
||||
#if OS_ATARI
|
||||
screensz(&LINES, &COLS);
|
||||
dofscroll = LINES/2;
|
||||
#endif
|
||||
|
||||
#if OS_RMX
|
||||
#if USE_TERMCAP
|
||||
{ FILE *tcf;
|
||||
extern char termcap[];
|
||||
|
||||
if (tcf=fopen(":termcap:","rb")) {
|
||||
fgets(termcap,200,tcf); /* get a line... */
|
||||
termcap[strlen(termcap)-1] = 0; /* erase \n at eof */
|
||||
fclose(tcf); /* close the file */
|
||||
}
|
||||
}
|
||||
#endif /*USE_TERMCAP*/
|
||||
settty();
|
||||
#endif /*OS_RMX*/
|
||||
|
||||
#if USE_TERMCAP
|
||||
tc_init();
|
||||
#endif
|
||||
|
||||
version(); strput(". Copyright (c) 1983-2007 by David Parsons");
|
||||
|
||||
if (!CA) {
|
||||
lineonly = TRUE;
|
||||
mvcur(0, 0);
|
||||
strput(CE);
|
||||
prints("(line mode)");
|
||||
}
|
||||
else
|
||||
lineonly = FALSE;
|
||||
|
||||
/* initialize macro table */
|
||||
for (i = 0;i < MAXMACROS;i++)
|
||||
mbuffer[i].token = 0;
|
||||
core[0] = EOL;
|
||||
|
||||
yank.size = ERR; /* no yanks yet */
|
||||
|
||||
undo.blockp = undo.ptr = 0;
|
||||
|
||||
fillchar(adjcurr, sizeof(adjcurr), 0);
|
||||
fillchar(adjendp, sizeof(adjendp), 0);
|
||||
|
||||
adjcurr[BTO_WD] = /* more practical to just leave dynamic */
|
||||
adjcurr[SENT_BACK] =
|
||||
adjendp[BTO_WD] =
|
||||
adjendp[FORWD] =
|
||||
adjendp[MATCHEXPR] =
|
||||
adjendp[PATT_BACK] =
|
||||
adjendp[TO_CHAR] =
|
||||
adjendp[UPTO_CHAR] =
|
||||
adjendp[PAGE_BEGIN] =
|
||||
adjendp[PAGE_MIDDLE]=
|
||||
adjendp[PAGE_END] = TRUE;
|
||||
|
||||
fillchar(contexts, sizeof(contexts), -1);
|
||||
|
||||
stamp(undobuf, "$un");
|
||||
stamp(yankbuf, "$ya");
|
||||
stamp(undotmp, "$tm");
|
||||
|
||||
mvcur(LINES-1,0);
|
||||
#if OS_ATARI
|
||||
mapslash = getenv("mapslash") != 0L;
|
||||
#endif
|
||||
#if OS_RMX
|
||||
do_file(":lvrc:", &xmode, &xquit);
|
||||
#else /*!OS_RMX system has a environment.. */
|
||||
{ char *p;
|
||||
extern char *execstr; /* [exec.c] */
|
||||
|
||||
if ( (p=getenv("LVRC")) ) {
|
||||
strcpy(instring,p);
|
||||
execstr = instring;
|
||||
setcmd();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
++args, --count;
|
||||
if (count > 0 && **args == '+') {
|
||||
char *p = *args;
|
||||
strcpy(startcmd, p[1] ? (1+p) : "$");
|
||||
++args, --count;
|
||||
}
|
||||
argc = 0;
|
||||
while (count-- > 0)
|
||||
expandargs(*args++, &argc, &argv);
|
||||
if (argc > 0) {
|
||||
strcpy(filenm, argv[0]);
|
||||
if (argc > 1)
|
||||
toedit(argc);
|
||||
inputf(filenm,TRUE);
|
||||
}
|
||||
else
|
||||
filenm[0] = 0;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
execmode(emode)
|
||||
exec_type emode;
|
||||
{
|
||||
bool more, /* used [more] at end of line */
|
||||
noquit; /* quit flag for :q, :xit, :wq */
|
||||
exec_type mode;
|
||||
|
||||
zotscreen = diddled = FALSE;
|
||||
noquit = TRUE;
|
||||
|
||||
if (lineonly)
|
||||
println();
|
||||
|
||||
mode=emode;
|
||||
do {
|
||||
prompt(FALSE,":");
|
||||
if (getlin(instring))
|
||||
exec(instring, &mode, &noquit);
|
||||
indirect = FALSE;
|
||||
if (mode == E_VISUAL && zotscreen && noquit) { /*ask for more*/
|
||||
prints(" [more]");
|
||||
if ((ch=peekc()) == 13 || ch == ' ' || ch == ':')
|
||||
readchar();
|
||||
more = (ch != ' ' && ch != 13);
|
||||
}
|
||||
else
|
||||
more = (mode == E_EDIT);
|
||||
if (mode != E_VISUAL && curpos.x > 0)
|
||||
println();
|
||||
else
|
||||
mvcur(-1,0);
|
||||
} while (more && noquit);
|
||||
if (zotscreen)
|
||||
clrprompt();
|
||||
return noquit;
|
||||
}
|
||||
|
||||
#if OS_ATARI
|
||||
long _STKSIZ = 4096;
|
||||
long _BLKSIZ = 4096;
|
||||
#endif
|
||||
|
||||
void /* should be union { void a; int b; float c; } to annoy the purists */
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
initialize(argc, argv);
|
||||
|
||||
diddled = TRUE; /* force screen redraw when we enter editcore() */
|
||||
if (lineonly)
|
||||
while (execmode(E_EDIT))
|
||||
prints("(no visual mode)");
|
||||
else
|
||||
while (execmode(editcore()))
|
||||
/* do nada */;
|
||||
|
||||
unlink(undobuf);
|
||||
unlink(yankbuf);
|
||||
|
||||
#if TTY_ZTERM
|
||||
zclose();
|
||||
#endif
|
||||
|
||||
fixcon();
|
||||
|
||||
#if OS_RMX
|
||||
strputs("\033]T:C15=3,C18=13,C20=5,C21=6,C23=4\033\\\n");
|
||||
dq$special(2,&fileno(stdin),&curr);
|
||||
#else
|
||||
println();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
479
src/cmd/levee/misc.c
Normal file
479
src/cmd/levee/misc.c
Normal file
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
bool PROC
|
||||
getlin(str)
|
||||
char *str;
|
||||
{
|
||||
int len;
|
||||
char flag;
|
||||
|
||||
flag = line(str, 0, COLS-curpos.x, &len);
|
||||
str[len] = 0;
|
||||
strput(CE);
|
||||
return (flag == EOL);
|
||||
} /* getlin */
|
||||
|
||||
|
||||
char PROC
|
||||
readchar()
|
||||
{
|
||||
ch = peekc(); /* get the peeked character */
|
||||
needchar = TRUE; /* force a read on next readchar/peekc */
|
||||
if (xerox) { /* save this character for redo */
|
||||
if (rcp >= &rcb[256-1]) /* oops, buffer overflow */
|
||||
error();
|
||||
else /* concat it at the end of rcb^ */
|
||||
*rcp++ = ch;
|
||||
}
|
||||
return ch;
|
||||
} /* readchar */
|
||||
|
||||
|
||||
/* look at next input character without actually using it */
|
||||
char PROC
|
||||
peekc()
|
||||
{
|
||||
if (needchar) { /* if buffer is empty, */
|
||||
if (macro >= 0) { /* if a macro */
|
||||
lastchar = *mcr[macro].ip;
|
||||
mcr[macro].ip++;
|
||||
if (*mcr[macro].ip == 0) {
|
||||
if (--mcr[macro].m_iter > 0)
|
||||
mcr[macro].ip = mcr[macro].mtext;
|
||||
else
|
||||
--macro;
|
||||
}
|
||||
}
|
||||
else /* else get one from the keyboard */
|
||||
lastchar = getKey();
|
||||
needchar = FALSE;
|
||||
}
|
||||
return lastchar;
|
||||
} /* peekc */
|
||||
|
||||
|
||||
/* find the amount of leading whitespace between start && limit.
|
||||
endd is the last bit of whitespace found.
|
||||
*/
|
||||
int PROC
|
||||
findDLE(start, endd, limit, dle)
|
||||
int start, *endd, limit, dle;
|
||||
{
|
||||
while ((core[start] == '\t' || core[start] == ' ') && start < limit) {
|
||||
if (core[start] == '\t')
|
||||
dle = tabsize * (1+(dle/tabsize));
|
||||
else
|
||||
dle++;
|
||||
start++;
|
||||
}
|
||||
*endd = start;
|
||||
return dle;
|
||||
} /* findDLE */
|
||||
|
||||
|
||||
int PROC
|
||||
skipws(loc)
|
||||
int loc;
|
||||
{
|
||||
while ((core[loc] == '\t' || core[loc] == ' ') && loc <= bufmax)
|
||||
loc++;
|
||||
return(loc);
|
||||
} /* skipws */
|
||||
|
||||
|
||||
int PROC
|
||||
setX(cp)
|
||||
int cp;
|
||||
{
|
||||
int top, xp;
|
||||
|
||||
top = bseekeol(cp);
|
||||
xp = 0;
|
||||
while (top < cp) {
|
||||
switch (cclass(core[top])) {
|
||||
case 0 : xp++; break;
|
||||
case 1 : xp += 2; break;
|
||||
case 2 : xp = tabsize*(1+(xp/tabsize)); break;
|
||||
case 3 : xp += 3; break;
|
||||
}
|
||||
top++;
|
||||
}
|
||||
return(xp);
|
||||
} /* setX */
|
||||
|
||||
|
||||
int PROC
|
||||
setY(cp)
|
||||
int cp;
|
||||
{
|
||||
int yp, ix;
|
||||
|
||||
ix = ptop;
|
||||
yp = -1;
|
||||
cp = min(cp,bufmax-1);
|
||||
do {
|
||||
yp++;
|
||||
ix = 1+fseekeol(ix);
|
||||
} while (ix <= cp);
|
||||
return(yp);
|
||||
} /* setY */
|
||||
|
||||
|
||||
int PROC
|
||||
to_line(cp)
|
||||
int cp;
|
||||
{
|
||||
int tdx,line;
|
||||
tdx = 0;
|
||||
line = 0;
|
||||
while (tdx <= cp) {
|
||||
tdx = 1+fseekeol(tdx);
|
||||
line++;
|
||||
}
|
||||
return(line);
|
||||
} /* to_line */
|
||||
|
||||
|
||||
int PROC
|
||||
to_index(line)
|
||||
int line;
|
||||
{
|
||||
int cp = 0;
|
||||
while (cp < bufmax && line > 1) {
|
||||
cp = 1+fseekeol(cp);
|
||||
line--;
|
||||
}
|
||||
return(cp);
|
||||
} /* to_index */
|
||||
|
||||
VOID PROC
|
||||
swap(a,b)
|
||||
int *a,*b;
|
||||
{
|
||||
int c;
|
||||
|
||||
c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
} /* swap */
|
||||
|
||||
|
||||
int PROC
|
||||
#if OS_ATARI
|
||||
cclass(c)
|
||||
register int c;
|
||||
{
|
||||
if (c >= ' ' && c < '')
|
||||
return 0;
|
||||
if (c == '\t' && !list)
|
||||
return 2;
|
||||
if (c >= 0)
|
||||
return 1;
|
||||
return 3;
|
||||
} /* cclass */
|
||||
#else
|
||||
cclass(c)
|
||||
register unsigned char c;
|
||||
{
|
||||
if (c == '\t' && !list)
|
||||
return 2;
|
||||
if (c == '' || c < ' ')
|
||||
return 1;
|
||||
#if !OS_DOS
|
||||
if (c & 0x80)
|
||||
return 3;
|
||||
#endif
|
||||
return 0;
|
||||
} /* cclass */
|
||||
#endif
|
||||
|
||||
#if OS_ATARI
|
||||
/*
|
||||
* wildly machine-dependent code to make a beep
|
||||
*/
|
||||
#include <atari\osbind.h>
|
||||
|
||||
static char sound[] = {
|
||||
0xA8,0x01,0xA9,0x01,0xAA,0x01,0x00,
|
||||
0xF8,0x10,0x10,0x10,0x00,0x20,0x03
|
||||
};
|
||||
|
||||
#define SADDR 0xFF8800L
|
||||
|
||||
typedef char srdef[4];
|
||||
|
||||
static srdef *SOUND = (srdef *)SADDR;
|
||||
|
||||
static
|
||||
beeper()
|
||||
{
|
||||
register i;
|
||||
for (i=0; i<sizeof(sound); i++) {
|
||||
(*SOUND)[0] = i;
|
||||
(*SOUND)[2] = sound[i];
|
||||
}
|
||||
} /* beeper */
|
||||
#endif /*OS_ATARI*/
|
||||
|
||||
|
||||
VOID PROC
|
||||
error()
|
||||
{
|
||||
indirect = FALSE;
|
||||
macro = -1;
|
||||
if (xerox)
|
||||
rcb[0] = 0;
|
||||
xerox = FALSE;
|
||||
#if OS_ATARI
|
||||
Supexec(beeper);
|
||||
#else
|
||||
if (bell)
|
||||
strput(BELL);
|
||||
#endif /*OS_ATARI*/
|
||||
} /* error */
|
||||
|
||||
|
||||
/* the dirty work to start up a macro */
|
||||
VOID PROC
|
||||
insertmacro(cmdstr, count)
|
||||
char *cmdstr;
|
||||
int count;
|
||||
{
|
||||
if (macro >= NMACROS)
|
||||
error();
|
||||
else if (*cmdstr != 0) {
|
||||
macro++;
|
||||
mcr[macro].mtext = cmdstr; /* point at the text */
|
||||
mcr[macro].ip = cmdstr; /* starting index */
|
||||
mcr[macro].m_iter = count; /* # times to do the macro */
|
||||
}
|
||||
} /* insertmacro */
|
||||
|
||||
|
||||
int PROC
|
||||
lookup(c)
|
||||
char c;
|
||||
{
|
||||
int ix = MAXMACROS;
|
||||
|
||||
while (--ix >= 0 && mbuffer[ix].token != c)
|
||||
;
|
||||
return ix;
|
||||
} /* lookup */
|
||||
|
||||
|
||||
VOID PROC
|
||||
fixmarkers(base,offset)
|
||||
int base,offset;
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
for (c = 0;c<'z'-'`';c++)
|
||||
if (contexts[c] > base) {
|
||||
if (contexts[c]+offset < base || contexts[c]+offset >= bufmax)
|
||||
contexts[c] = -1;
|
||||
else
|
||||
contexts[c] += offset;
|
||||
}
|
||||
} /* fixmarkers */
|
||||
|
||||
|
||||
VOID PROC
|
||||
wr_stat()
|
||||
{
|
||||
clrprompt();
|
||||
if (filenm[0] != 0) {
|
||||
printch('"');
|
||||
prints(filenm);
|
||||
prints("\" ");
|
||||
if (newfile)
|
||||
prints("<New file> ");
|
||||
}
|
||||
else
|
||||
prints("No file");
|
||||
printch(' ');
|
||||
if (readonly)
|
||||
prints("<readonly> ");
|
||||
else if (modified)
|
||||
prints("<Modified> ");
|
||||
if (bufmax > 0) {
|
||||
prints(" line ");
|
||||
printi(to_line(curr));
|
||||
prints(" -");
|
||||
printi((int)((long)(curr*100L)/(long)bufmax));
|
||||
prints("%-");
|
||||
}
|
||||
else
|
||||
prints("-empty-");
|
||||
} /* wr_stat */
|
||||
|
||||
|
||||
static int tabptr,
|
||||
tabstack[20],
|
||||
ixp;
|
||||
|
||||
VOID PROC
|
||||
back_up(c)
|
||||
char c;
|
||||
{
|
||||
switch (cclass(c)) {
|
||||
case 0: ixp--; break;
|
||||
case 1: ixp -= 2; break;
|
||||
case 2: ixp = tabstack[--tabptr]; break;
|
||||
case 3: ixp -= 3; break;
|
||||
}
|
||||
mvcur(-1,ixp);
|
||||
} /* back_up */
|
||||
|
||||
|
||||
/*
|
||||
* put input into buf[] || instring[].
|
||||
* return states are:
|
||||
* 0 : backed over beginning
|
||||
* ESC : ended with an ESC
|
||||
* EOL : ended with an '\r'
|
||||
*/
|
||||
char PROC
|
||||
line(s, start, endd, size)
|
||||
char *s;
|
||||
int start, endd, *size;
|
||||
{
|
||||
int col0,
|
||||
ip;
|
||||
unsigned char c;
|
||||
|
||||
col0 = ixp = curpos.x;
|
||||
ip = start;
|
||||
tabptr = 0;
|
||||
while (1) {
|
||||
c = readchar();
|
||||
if (movemap[c] == INSMACRO) /* map!ped macro */
|
||||
insertmacro(mbuffer[lookup(c)].m_text, 1);
|
||||
else if (c == DW) {
|
||||
while (!wc(s[ip-1]) && ip > start)
|
||||
back_up(s[--ip]);
|
||||
while (wc(s[ip-1]) && ip > start)
|
||||
back_up(s[--ip]);
|
||||
}
|
||||
else if (c == eraseline) {
|
||||
ip = start;
|
||||
tabptr = 0;
|
||||
mvcur(-1,ixp=col0);
|
||||
}
|
||||
else if (c==Erasechar) {
|
||||
if (ip>start)
|
||||
back_up(s[--ip]);
|
||||
else {
|
||||
*size = 0;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else if (c=='\r' || c==ESC) {
|
||||
*size = (ip-start);
|
||||
return (c==ESC) ? ESC : EOL;
|
||||
}
|
||||
else if ((!beautify) || c == TAB || c == ''
|
||||
|| (c >= ' ' && c <= '~')) {
|
||||
if (ip < endd) {
|
||||
if (c == '')
|
||||
c = readchar();
|
||||
switch (cclass(c)) {
|
||||
case 0 : ixp++; break;
|
||||
case 1 : ixp += 2; break;
|
||||
case 2 :
|
||||
tabstack[tabptr++] = ixp;
|
||||
ixp = tabsize*(1+(ixp/tabsize));
|
||||
break;
|
||||
case 3 : ixp += 3; break;
|
||||
}
|
||||
s[ip++] = c;
|
||||
printch(c);
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
} /* line */
|
||||
|
||||
|
||||
/* move to core[loc] */
|
||||
VOID PROC
|
||||
setpos(loc)
|
||||
int loc;
|
||||
{
|
||||
lstart = bseekeol(loc);
|
||||
lend = fseekeol(loc);
|
||||
xp = setX(loc);
|
||||
curr = loc;
|
||||
} /* setpos */
|
||||
|
||||
|
||||
VOID PROC
|
||||
resetX()
|
||||
{
|
||||
if (deranged) {
|
||||
xp = setX(curr);
|
||||
mvcur(-1, xp);
|
||||
deranged = FALSE;
|
||||
}
|
||||
} /* resetX */
|
||||
|
||||
|
||||
/* set end of window */
|
||||
VOID PROC
|
||||
setend()
|
||||
{
|
||||
int bottom, count;
|
||||
|
||||
bottom = ptop;
|
||||
count = LINES-1;
|
||||
while (bottom < bufmax && count > 0) {
|
||||
bottom = 1+fseekeol(bottom);
|
||||
count--;
|
||||
}
|
||||
pend = bottom-1; /* last char before eol || eof */
|
||||
} /* setend */
|
||||
|
||||
|
||||
/* set top of window
|
||||
* return the number of lines actually between curr && ptop.
|
||||
*/
|
||||
int PROC
|
||||
settop(lines)
|
||||
int lines;
|
||||
{
|
||||
int top, yp;
|
||||
|
||||
top = curr;
|
||||
yp = -1;
|
||||
do {
|
||||
yp++;
|
||||
top = bseekeol(top) - 1;
|
||||
lines--;
|
||||
} while (top >= 0 && lines > 0);
|
||||
ptop = top+1; /* tah-dah */
|
||||
setend();
|
||||
return(yp);
|
||||
} /* settop */
|
||||
197
src/cmd/levee/modify.c
Normal file
197
src/cmd/levee/modify.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
#include "grep.h"
|
||||
|
||||
/* modification commands that can be accessed by either editcore || execmode */
|
||||
|
||||
/* put stuff into the yank buffer */
|
||||
|
||||
bool PROC
|
||||
doyank(low, high)
|
||||
int low, high;
|
||||
{
|
||||
HANDLE f;
|
||||
register int sz;
|
||||
|
||||
yank.size = high - low;
|
||||
moveleft(&core[low], yank.stuff, min(yank.size, SBUFSIZE));
|
||||
if (yank.size > SBUFSIZE) {
|
||||
if ((f=OPEN_NEW(yankbuf)) >= 0) {
|
||||
low += SBUFSIZE;
|
||||
sz = WRITE_TEXT(f, core+low, high-low);
|
||||
CLOSE_FILE(f);
|
||||
if (sz == high-low)
|
||||
return TRUE;
|
||||
}
|
||||
yank.size = -1;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
deletion(low, high)
|
||||
int low,high;
|
||||
{
|
||||
if (doyank(low, high)) /* fill yank buffer */
|
||||
return delete_to_undo(&undo, low, high-low);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* move stuff from the yank buffer into core */
|
||||
|
||||
bool PROC
|
||||
putback(start, newend)
|
||||
int start, *newend;
|
||||
{
|
||||
int siz, st;
|
||||
HANDLE f;
|
||||
|
||||
if (yank.size+bufmax < SIZE && yank.size > 0) {
|
||||
*newend = start + yank.size;
|
||||
if (start < bufmax)
|
||||
moveright(&core[start], &core[start+yank.size], bufmax-start);
|
||||
moveleft(yank.stuff, &core[start], min(SBUFSIZE, yank.size));
|
||||
if (yank.size > SBUFSIZE) {
|
||||
siz = yank.size - SBUFSIZE;
|
||||
if ((f=OPEN_OLD(yankbuf)) >= 0) {
|
||||
st = READ_TEXT(f, &core[start+SBUFSIZE], siz);
|
||||
CLOSE_FILE(f);
|
||||
if (st == siz)
|
||||
goto succeed;
|
||||
}
|
||||
moveleft(&core[start+yank.size], &core[start], bufmax-start);
|
||||
*newend = -1;
|
||||
return FALSE;
|
||||
}
|
||||
succeed:
|
||||
insert_to_undo(&undo, start, yank.size);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define DSIZE 1024
|
||||
|
||||
int PROC
|
||||
makedest(str,start,ssize,size)
|
||||
/* makedest: make the replacement string for an regular expression */
|
||||
char *str;
|
||||
int start, ssize, size;
|
||||
{
|
||||
char *fr = dst;
|
||||
char *to = str;
|
||||
int as, asize, c;
|
||||
|
||||
while (*fr && size >= 0) {
|
||||
if (*fr == AMPERSAND) { /* & copies in the pattern that we matched */
|
||||
if ((size -= ssize) < 0)
|
||||
return -1;
|
||||
moveleft(&core[start],to,ssize);
|
||||
to += ssize;
|
||||
fr++;
|
||||
}
|
||||
else if (*fr == ESCAPE) { /* \1 .. \9 do arguments */
|
||||
c = fr[1];
|
||||
fr += 2;
|
||||
if (c >= '1' && c <= '9') {
|
||||
if ((as = RE_start[c-'1']) < 0)
|
||||
continue;
|
||||
asize = RE_size [c-'1'];
|
||||
if ((size -= asize) < 0)
|
||||
return -1;
|
||||
moveleft(&core[as],to,asize);
|
||||
to += asize;
|
||||
}
|
||||
else
|
||||
*to++ = c;
|
||||
}
|
||||
else {
|
||||
*to++ = *fr++;
|
||||
--size;
|
||||
}
|
||||
}
|
||||
return to-str;
|
||||
}
|
||||
|
||||
int PROC
|
||||
chop(start,endd,visual,query)
|
||||
int start,*endd;
|
||||
bool visual, *query;
|
||||
{
|
||||
int i,retval;
|
||||
char c;
|
||||
/*>>>>
|
||||
bool ok;
|
||||
<<<<*/
|
||||
char dest[DSIZE];
|
||||
register int len, dlen;
|
||||
|
||||
retval = -1;
|
||||
/*dlen = strlen(dst);*/
|
||||
restart:
|
||||
count = 1;
|
||||
i = findfwd(pattern, start, *endd);
|
||||
if (i != ERR) {
|
||||
if (*query) {
|
||||
/*>>>> don't delete -- keep for future use
|
||||
if (visual) {
|
||||
mvcur(yp,setX(i));puts("?");
|
||||
}
|
||||
else {
|
||||
<<<<*/
|
||||
println();
|
||||
writeline(-1,-1,bseekeol(i));
|
||||
println();
|
||||
mvcur(-1,setX(i));
|
||||
prints("^?");
|
||||
/*>>>>
|
||||
}
|
||||
<<<<*/
|
||||
do
|
||||
c = tolower(readchar());
|
||||
while (c!='y'&&c!='n'&&c!='q'&&c!='a');
|
||||
if (c == 'n') {
|
||||
start = i+1;
|
||||
goto restart;
|
||||
}
|
||||
else if (c == 'q')
|
||||
return retval;
|
||||
else if (c == 'a')
|
||||
*query = FALSE;
|
||||
}
|
||||
len = lastp-i;
|
||||
dlen = makedest(dest, i, len, DSIZE);
|
||||
if (dlen >= 0 && bufmax-(int)(len+dlen) < SIZE
|
||||
&& delete_to_undo(&undo, i, len)) {
|
||||
modified = TRUE;
|
||||
if (dlen > 0) {
|
||||
moveright(&core[i], &core[i+dlen], bufmax-i);
|
||||
insert_to_undo(&undo,i,dlen);
|
||||
moveleft(dest,&core[i],dlen);
|
||||
}
|
||||
*endd += (dlen-len);
|
||||
retval = i+dlen;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
444
src/cmd/levee/move.c
Normal file
444
src/cmd/levee/move.c
Normal file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
int PROC findcol();
|
||||
int PROC moveword();
|
||||
int PROC sentence();
|
||||
int PROC match();
|
||||
int PROC fchar(), bchar();
|
||||
|
||||
/* driver for movement commands */
|
||||
|
||||
findstates PROC
|
||||
findCP(curp,newpos,cmd)
|
||||
int curp, *newpos;
|
||||
cmdtype cmd;
|
||||
{
|
||||
static char chars[2] = {'/','?'};
|
||||
char tsearch;
|
||||
|
||||
*newpos = ERR;
|
||||
switch (cmd) { /* move around */
|
||||
|
||||
case GO_LEFT:
|
||||
*newpos = max(lstart, curp-max(count,1));
|
||||
break;
|
||||
|
||||
case GO_RIGHT:
|
||||
*newpos = min(lend, curp+max(count,1));
|
||||
break;
|
||||
|
||||
case GO_UP:
|
||||
case GO_DOWN:
|
||||
*newpos = nextline(cmd==GO_DOWN, curp, count);
|
||||
if (*newpos >= 0 && *newpos < bufmax)
|
||||
*newpos = findcol(*newpos,xp);
|
||||
break;
|
||||
|
||||
case FORWD:
|
||||
case TO_WD:
|
||||
case BACK_WD:
|
||||
case BTO_WD:
|
||||
*newpos = moveword(curp,(cmd <= TO_WD),(cmd==TO_WD || cmd==BTO_WD));
|
||||
break;
|
||||
|
||||
case NOTWHITE:
|
||||
*newpos = skipws(bseekeol(curp));
|
||||
break;
|
||||
|
||||
case TO_COL:
|
||||
*newpos = findcol(curp, count);
|
||||
break;
|
||||
|
||||
case TO_EOL:
|
||||
while ( (count-- > 1) && (curp < bufmax) )
|
||||
curp = 1+fseekeol(curp);
|
||||
*newpos = fseekeol(curp);
|
||||
break;
|
||||
|
||||
case PARA_FWD:
|
||||
do
|
||||
curp = findfwd("^*[ \t$",curp+1,bufmax-1);
|
||||
while (curp != ERR && --count > 0);
|
||||
*newpos = (curp==ERR)?bufmax:curp;
|
||||
break;
|
||||
|
||||
case PARA_BACK:
|
||||
do
|
||||
curp = findback("^*[ \t$",curp-1,0);
|
||||
while (curp != ERR && --count > 0);
|
||||
*newpos = (curp==ERR)?0:curp;
|
||||
break;
|
||||
|
||||
case SENT_FWD:
|
||||
case SENT_BACK:
|
||||
*newpos = sentence(curp, cmd==SENT_FWD);
|
||||
break;
|
||||
|
||||
case MATCHEXPR:
|
||||
*newpos = match(curp);
|
||||
break;
|
||||
|
||||
case TO_CHAR:
|
||||
case UPTO_CHAR:
|
||||
case BACK_CHAR:
|
||||
case BACKTO_CHAR:
|
||||
ch = readchar();
|
||||
if (ch == ESC)
|
||||
return ESCAPED;
|
||||
if (cmd<=UPTO_CHAR) {
|
||||
*newpos = fchar(curp,*newpos);
|
||||
if (cmd==UPTO_CHAR && *newpos>=0)
|
||||
*newpos = max(curp, *newpos-1);
|
||||
}
|
||||
else {
|
||||
*newpos = bchar(curp,*newpos);
|
||||
if (cmd==BACKTO_CHAR && *newpos>=0)
|
||||
*newpos = min(curp, *newpos+1);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAGE_BEGIN:
|
||||
*newpos = ptop;
|
||||
break;
|
||||
|
||||
case PAGE_END:
|
||||
*newpos = pend;
|
||||
break;
|
||||
|
||||
case PAGE_MIDDLE:
|
||||
curp = ptop;
|
||||
count = 12;
|
||||
while (count-- > 0 && curp < bufmax)
|
||||
curp = 1+fseekeol(curp);
|
||||
*newpos = skipws(curp);
|
||||
break;
|
||||
|
||||
case GLOBAL_LINE:
|
||||
if (count <= 0)
|
||||
*newpos = bufmax-1;
|
||||
else
|
||||
*newpos = to_index(count);
|
||||
break;
|
||||
|
||||
case TO_MARK:
|
||||
case TO_MARK_LINE:
|
||||
*newpos = getcontext((char)tolower(readchar()), cmd==TO_MARK_LINE);
|
||||
break;
|
||||
|
||||
case CR_FWD:
|
||||
case CR_BACK:
|
||||
curp = nextline(cmd==CR_FWD, curp, count);
|
||||
if (cmd==CR_BACK && curp > 0)
|
||||
curp = bseekeol(curp);
|
||||
*newpos = skipws(curp);
|
||||
break;
|
||||
|
||||
case PATT_FWD:
|
||||
case PATT_BACK: /* search for pattern */
|
||||
case FSEARCH:
|
||||
case BSEARCH:
|
||||
clrprompt();
|
||||
if (cmd == PATT_FWD || cmd == PATT_BACK) {
|
||||
printch(tsearch = instring[0] = chars[cmd-PATT_FWD]);
|
||||
if (!getlin(&instring[1]))
|
||||
return ESCAPED; /* needs to skip later tests */
|
||||
}
|
||||
else {
|
||||
if (!lsearch)
|
||||
return BADMOVE;
|
||||
tsearch = lsearch;
|
||||
printch(instring[0] = (cmd==FSEARCH)?lsearch:((lsearch=='?')?'/':'?') );
|
||||
prints(lastpatt);
|
||||
instring[1] = 0;
|
||||
}
|
||||
if (*findparse(instring, newpos, curp)) { /* croaked patt */
|
||||
*newpos = ERR;
|
||||
prompt(TRUE,"bad pattern");
|
||||
}
|
||||
else if (*newpos == ERR)
|
||||
prompt(FALSE,"no match");
|
||||
lsearch = tsearch; /* fixup for N, n */
|
||||
break;
|
||||
}
|
||||
if ( ((*newpos) >= 0) && ((*newpos) <= bufmax) )
|
||||
return LEGALMOVE;
|
||||
return BADMOVE;
|
||||
}
|
||||
|
||||
/* this procedure handles all movement in visual mode */
|
||||
|
||||
VOID PROC
|
||||
movearound(cmd)
|
||||
cmdtype cmd;
|
||||
{
|
||||
int cp;
|
||||
|
||||
switch (findCP(curr, &cp, cmd)) {
|
||||
case LEGALMOVE:
|
||||
if (cp < bufmax) {
|
||||
if (cmd >= PATT_FWD) /* absolute move */
|
||||
contexts[0] = curr; /* so save old position... */
|
||||
curr = cp; /* goto new position */
|
||||
if (cmd==GO_UP || cmd==GO_DOWN) /* reset Xpos */
|
||||
deranged = TRUE;
|
||||
else
|
||||
xp = setX(cp); /* just reset XP */
|
||||
if (cp < lstart || cp > lend) {
|
||||
lstart = bseekeol(curr);
|
||||
lend = fseekeol(curr);
|
||||
if (curr < ptop) {
|
||||
if (canUPSCROLL && ok_to_scroll(curr, ptop)) {
|
||||
scrollback(curr);
|
||||
yp = 0;
|
||||
}
|
||||
else {
|
||||
yp = settop(LINES / 2);
|
||||
redisplay(TRUE);
|
||||
}
|
||||
}
|
||||
else if (curr > pend) {
|
||||
if (ok_to_scroll(pend, curr)) {
|
||||
scrollforward(curr);
|
||||
yp = LINES-2;
|
||||
}
|
||||
else {
|
||||
yp = settop(LINES / 2);
|
||||
redisplay(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
yp = setY(curr);
|
||||
}
|
||||
}
|
||||
else
|
||||
error();
|
||||
break;
|
||||
case BADMOVE:
|
||||
error();
|
||||
break;
|
||||
}
|
||||
mvcur(yp, xp);
|
||||
}
|
||||
|
||||
int PROC
|
||||
findcol(ip, col)
|
||||
int ip, col;
|
||||
{
|
||||
int tcol, endd;
|
||||
|
||||
ip = bseekeol(ip); /* start search here */
|
||||
endd = fseekeol(ip); /* end search here */
|
||||
|
||||
tcol = 0;
|
||||
while (tcol < col && ip < endd)
|
||||
switch (cclass(core[ip++])) {
|
||||
case 0: tcol++; break;
|
||||
case 1: tcol += 2; break;
|
||||
case 3: tcol += 3; break;
|
||||
case 2: tcol = tabsize*(1+(tcol/tabsize)); break;
|
||||
}
|
||||
return(ip);
|
||||
}
|
||||
|
||||
char dstpatt[]="[](){}", srcpatt[]="][)(}{";
|
||||
|
||||
/* find matching [], (), {} */
|
||||
|
||||
int PROC
|
||||
match(p)
|
||||
int p;
|
||||
{
|
||||
char srcchar, dstchar;
|
||||
int lev, step;
|
||||
|
||||
while((lev = scan(6,'=',core[p],srcpatt)) >= 6 && core[p] != EOL)
|
||||
p++;
|
||||
if (lev < 6) {
|
||||
srcchar = srcpatt[lev];
|
||||
dstchar = dstpatt[lev];
|
||||
step = setstep[lev&1];
|
||||
lev = 0;
|
||||
while (p >= 0 && p < bufmax) {
|
||||
p += step;
|
||||
if (core[p] == srcchar)
|
||||
lev++;
|
||||
else if (core[p] == dstchar)
|
||||
if(--lev < 0)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
char * PROC
|
||||
class(c)
|
||||
/* find the character class of a char -- for word movement */
|
||||
char c;
|
||||
{
|
||||
if (strchr(wordset,c))
|
||||
return wordset;
|
||||
else if (strchr(spaces,c))
|
||||
return spaces;
|
||||
else
|
||||
return (char*)NULL;
|
||||
}
|
||||
|
||||
int PROC
|
||||
skip(chars,cp,step)
|
||||
/* skip past characters in a character class */
|
||||
char *chars;
|
||||
register int cp;
|
||||
int step;
|
||||
{
|
||||
while (cp >= 0 && cp < bufmax && strchr(chars,core[cp]))
|
||||
cp += step;
|
||||
return cp;
|
||||
}
|
||||
|
||||
int PROC
|
||||
tow(cp,step)
|
||||
/* skip to the start of the next word */
|
||||
register int cp;
|
||||
register int step;
|
||||
{
|
||||
while (cp >= 0 && cp < bufmax
|
||||
&& !(strchr(wordset,core[cp]) || strchr(spaces,core[cp])))
|
||||
cp += step;
|
||||
return cp;
|
||||
}
|
||||
|
||||
int PROC
|
||||
moveword(cp,forwd,toword)
|
||||
/* word movement */
|
||||
int cp;
|
||||
bool forwd, toword;
|
||||
{
|
||||
int step;
|
||||
char *ccl;
|
||||
|
||||
step = setstep[forwd]; /* set direction to move.. */
|
||||
if (!toword)
|
||||
cp += step; /* advance one character */
|
||||
count = max(1,count);
|
||||
ccl = class(core[cp]);
|
||||
if (toword && ccl == spaces) { /* skip to start of word */
|
||||
count--;
|
||||
cp = skip(spaces,cp,step);
|
||||
ccl = class(core[cp]);
|
||||
}
|
||||
|
||||
while (cp >= 0 && cp < bufmax && count-- > 0) {
|
||||
if (ccl == spaces) {
|
||||
cp = skip(spaces,cp,step);
|
||||
ccl = class(core[cp]);
|
||||
}
|
||||
cp = (ccl)?skip(ccl,cp,step):tow(cp,step);
|
||||
ccl = class(core[cp]);
|
||||
}
|
||||
if (toword) { /* past whitespace? */
|
||||
if (ccl == spaces)
|
||||
cp = skip(spaces,cp,step);
|
||||
return cp;
|
||||
}
|
||||
return cp-step; /* sit on last character. */
|
||||
}
|
||||
|
||||
/* find a character forward on current line */
|
||||
|
||||
int PROC
|
||||
fchar(pos,npos)
|
||||
int pos,npos;
|
||||
{
|
||||
do
|
||||
pos += scan(lend-pos-1,'=',ch, &core[pos+1]) + 1;
|
||||
while (--count>0 && pos<lend);
|
||||
if (pos<lend)
|
||||
return(pos);
|
||||
return(npos);
|
||||
}
|
||||
|
||||
/* find a character backward on the current line */
|
||||
|
||||
int PROC
|
||||
bchar(pos,npos)
|
||||
int pos,npos;
|
||||
{
|
||||
do
|
||||
pos += scan(-pos+lstart+1,'=',ch, &core[pos-1]) - 1;
|
||||
while (--count>0 && pos>=lstart);
|
||||
if (pos>=lstart)
|
||||
return(pos);
|
||||
return(npos);
|
||||
}
|
||||
|
||||
/* look for the end of a sentence forward */
|
||||
|
||||
int PROC
|
||||
ahead(i)
|
||||
int i;
|
||||
{
|
||||
char c;
|
||||
|
||||
do {
|
||||
if ((c=core[i]) == '.' || c == '?' || c == '!')
|
||||
if (i == bufmax-1 || (c=core[1+i]) == TAB || c == EOL || c == ' ')
|
||||
return i;
|
||||
|
||||
} while (++i < bufmax);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look for the end of a sentence backwards. */
|
||||
|
||||
int PROC
|
||||
back(i)
|
||||
int i;
|
||||
{
|
||||
char c;
|
||||
|
||||
do {
|
||||
if ((c=core[i]) == '.' || c == '?' || c == '!')
|
||||
if ((c=core[1+i]) == TAB || c == EOL || c == ' ')
|
||||
return i;
|
||||
|
||||
} while (--i >= 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find the end of the next/last sentence.
|
||||
Sentences are delimited by ., !, or ? followed by a space.
|
||||
*/
|
||||
|
||||
int PROC
|
||||
sentence(start,forwd)
|
||||
int start;
|
||||
bool forwd;
|
||||
{
|
||||
do {
|
||||
if (forwd)
|
||||
start = ahead(start+1);
|
||||
else
|
||||
start = back(start-1);
|
||||
} while (--count > 0 && start >= 0);
|
||||
return start;
|
||||
}
|
||||
207
src/cmd/levee/os2call.c
Normal file
207
src/cmd/levee/os2call.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* os2 (and bound) interface for levee (Microsoft C)
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#if OS2
|
||||
|
||||
#include <signal.h>
|
||||
#include <glob.h>
|
||||
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
|
||||
int PROC
|
||||
min(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a>b) ? b : a;
|
||||
}
|
||||
|
||||
int PROC
|
||||
max(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a<b) ? b : a;
|
||||
}
|
||||
|
||||
PROC
|
||||
strput(s)
|
||||
char *s;
|
||||
{
|
||||
write(1, s, strlen(s));
|
||||
}
|
||||
|
||||
/* get a key, mapping certain control sequences
|
||||
*/
|
||||
PROC
|
||||
getKey()
|
||||
{
|
||||
register c;
|
||||
|
||||
c = getch();
|
||||
|
||||
if (c == 0 || c == 0xe0)
|
||||
switch (c=getch()) {
|
||||
case 'K': return LTARROW;
|
||||
case 'M': return RTARROW;
|
||||
case 'H': return UPARROW;
|
||||
case 'P': return DNARROW;
|
||||
case 'I': return 'U'-'@'; /* page-up */
|
||||
case 'Q': return 'D'-'@'; /* page-down */
|
||||
default : return 0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* don't allow interruptions to happen
|
||||
*/
|
||||
PROC
|
||||
nointr()
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
} /* nointr */
|
||||
|
||||
|
||||
/* have ^C do what it usually does
|
||||
*/
|
||||
PROC
|
||||
allowintr()
|
||||
{
|
||||
signal(SIGINT, SIG_DFL);
|
||||
} /* allowintr */
|
||||
|
||||
|
||||
/*
|
||||
* basename() returns the filename part of a pathname
|
||||
*/
|
||||
char *
|
||||
basename(s)
|
||||
register char *s;
|
||||
{
|
||||
register char *p = s;
|
||||
|
||||
for (p = s+strlen(s); p > s; --p)
|
||||
if (p[-1] == '/' || p[-1] == '\\' || p[-1] == ':')
|
||||
return p;
|
||||
return s;
|
||||
} /* basename */
|
||||
|
||||
|
||||
/*
|
||||
* glob() expands a wildcard, via calls to DosFindFirst/Next()
|
||||
* and pathname retention.
|
||||
*/
|
||||
char *
|
||||
glob(path, dta)
|
||||
char *path;
|
||||
struct glob_t *dta;
|
||||
{
|
||||
static char path_bfr[256]; /* full pathname to return */
|
||||
static char *file_part; /* points at file - for filling */
|
||||
static char isdotpattern; /* looking for files starting with . */
|
||||
static char isdotordotdot; /* special case . or .. */
|
||||
static struct glob_t *dta_bfr; /* pointer to desired dta */
|
||||
static FILEFINDBUF ffb; /* DOS & OS/2 dta */
|
||||
static int dir; /* directory handle */
|
||||
|
||||
register st; /* status from DosFindxxx */
|
||||
int count=1; /* how many files to find */
|
||||
|
||||
if (path) {
|
||||
/* when we start searching, save the path part of the filename in
|
||||
* a safe place.
|
||||
*/
|
||||
strcpy(path_bfr, path);
|
||||
file_part = basename(path_bfr);
|
||||
|
||||
/* set up initial parameters for DosFindFirst()
|
||||
*/
|
||||
dta_bfr = dta;
|
||||
dir = HDIR_SYSTEM;
|
||||
|
||||
if (isdotpattern = (*file_part == '.'))
|
||||
/* DosFindFirst() magically expands . and .. into their
|
||||
* directory names. Admittedly, there are cases where
|
||||
* this can be useful, but this is not one of them. So,
|
||||
* if we find that we're matching . and .., we just
|
||||
* special-case ourselves into oblivion to get around
|
||||
* this particular bit of DOS silliness.
|
||||
*/
|
||||
isdotordotdot = (file_part[1] == 0 || file_part[1] == '.');
|
||||
else
|
||||
isdotordotdot = 0;
|
||||
|
||||
st = DosFindFirst(path, &dir, 0x16, &ffb, sizeof ffb, &count, 0L);
|
||||
}
|
||||
else
|
||||
st = DosFindNext(dir, &ffb, sizeof ffb, &count);
|
||||
|
||||
while (st == 0 && count > 0) {
|
||||
/* Unless the pattern has a leading ., don't include any file
|
||||
* that starts with .
|
||||
*/
|
||||
if (ffb.achName[0] == '.' && !isdotpattern) {
|
||||
count = 1;
|
||||
st = DosFindNext(dir, &ffb, sizeof ffb, &count);
|
||||
}
|
||||
else {
|
||||
/* found a file - affix the path leading to it, then return
|
||||
* a pointer to the (static) buffer holding the path+the name.
|
||||
*/
|
||||
strlwr(ffb.achName); /* DOS & OS/2 are case-insensitive */
|
||||
|
||||
if (dta_bfr) {
|
||||
memcpy(&dta_bfr->wr_date, &ffb.fdateLastWrite, sizeof(short));
|
||||
memcpy(&dta_bfr->wr_time, &ffb.ftimeLastWrite, sizeof(short));
|
||||
if (isdotordotdot)
|
||||
strcpy(dta_bfr->name, file_part);
|
||||
else {
|
||||
strncpy(dta_bfr->name,
|
||||
ffb.achName, sizeof(dta_bfr->name)-1);
|
||||
dta_bfr->name[sizeof(dta_bfr->name)-1] = 0;
|
||||
}
|
||||
dta_bfr->size = ffb.cbFile;
|
||||
dta_bfr->attrib = ffb.attrFile;
|
||||
}
|
||||
if (!isdotordotdot)
|
||||
strcpy(file_part, ffb.achName);
|
||||
return path_bfr;
|
||||
}
|
||||
}
|
||||
/* nothing matched
|
||||
*/
|
||||
if (path && isdotordotdot) {
|
||||
/* must be at root, so statting dot will most likely fail. Fake a
|
||||
* dta.
|
||||
*/
|
||||
if (dta_bfr) {
|
||||
memset(dta_bfr, 0, sizeof *dta_bfr);
|
||||
dta_bfr->attrib = 0x10;
|
||||
dta_bfr->name[0] = '.';
|
||||
}
|
||||
return path_bfr;
|
||||
}
|
||||
return (char*)0;
|
||||
} /* glob */
|
||||
#endif
|
||||
162
src/cmd/levee/proto.h
Normal file
162
src/cmd/levee/proto.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
** levee function prototypes
|
||||
** (generated by cl -Gms -Ox -nologo -I../tools -Zg)
|
||||
*/
|
||||
#ifndef _PROTO_D
|
||||
#define _PROTO_D
|
||||
char *PROC badccl(char *src);
|
||||
char *PROC class(char c);
|
||||
char *PROC dodash(char *src);
|
||||
char *PROC findbounds(char *ip);
|
||||
char *PROC findparse(char *src,int *idx,int start);
|
||||
char *PROC getarg(void);
|
||||
char *PROC getname(void);
|
||||
char *PROC makepat(char *string,char delim);
|
||||
char *PROC search(char *pat,int *start);
|
||||
char *basename(char *s);
|
||||
char *glob(char *path,struct glob_t *dta);
|
||||
char PROC editcore(void);
|
||||
char PROC esc(char * *s);
|
||||
char PROC findCP(int curp,int *newpos,char cmd);
|
||||
char PROC line(char *s,int start,int endd,int *size);
|
||||
char PROC peekc(void);
|
||||
char PROC readchar(void);
|
||||
int PROC REmatch(char *pattern,int start,int end);
|
||||
int PROC addarg(char *name);
|
||||
int PROC addfile(struct _iobuf *f,int start,int endd,int *size);
|
||||
int PROC adjuster(int sleft,int endd,int sw);
|
||||
int PROC ahead(int i);
|
||||
int PROC allowintr(void);
|
||||
int PROC amatch(char *pattern,char *start,char *endp);
|
||||
int PROC args(void);
|
||||
int PROC back(int i);
|
||||
int PROC back_up(char c);
|
||||
int PROC backup(char *name);
|
||||
int PROC bchar(int pos,int npos);
|
||||
int PROC bigreplace(void);
|
||||
int PROC bseekeol(int origin);
|
||||
int PROC cclass(unsigned char c);
|
||||
int PROC chop(int start,int *endd,int visual,int *query);
|
||||
int PROC clrmsg(void);
|
||||
int PROC clrprompt(void);
|
||||
int PROC concatch(char c);
|
||||
int PROC copyover(struct undostack *save_undo,int *curp);
|
||||
int PROC cutandpaste(void);
|
||||
int PROC delete_to_undo(struct undostack *u,int start,int lump);
|
||||
int PROC deletion(int low,int high);
|
||||
int PROC do_file(char *fname,char *mode,int *noquit);
|
||||
int PROC doaddwork(char *token,int *argcp,char * * *argvp);
|
||||
int PROC docommand(char cmd);
|
||||
int PROC doinput(char *name);
|
||||
int PROC doins(int flag);
|
||||
int PROC doyank(int low,int high);
|
||||
int PROC editfile(void);
|
||||
int PROC errmsg(char *msg);
|
||||
int PROC error(void);
|
||||
int PROC exec(char *cmd,char *mode,int *noquit);
|
||||
int PROC execmode(char emode);
|
||||
int PROC exmacro(void);
|
||||
int PROC expandargs(char *name,int *argcp,char * * *argvp);
|
||||
int PROC fchar(int pos,int npos);
|
||||
int PROC findDLE(int start,int *endd,int limit,int dle);
|
||||
int PROC findarg(char *name);
|
||||
int PROC findback(char *pattern,int start,int endp);
|
||||
int PROC findcol(int ip,int col);
|
||||
int PROC findfwd(char *pattern,int start,int endp);
|
||||
int PROC fixcore(int *topp);
|
||||
int PROC fixmarkers(int base,int offset);
|
||||
int PROC fixupline(int dft);
|
||||
int PROC format(char *out,unsigned short c);
|
||||
int PROC fseekeol(int origin);
|
||||
int PROC gcount(void);
|
||||
int PROC getKey(void);
|
||||
int PROC getcontext(char c,int begline);
|
||||
int PROC getlin(char *str);
|
||||
int PROC initialize(int count,char * *args);
|
||||
int PROC inputf(char *fname,int newbuf);
|
||||
int PROC insert_to_undo(struct undostack *u,int start,int size);
|
||||
int PROC insertion(int count,int openflag,int *dp,int *yp,int visual);
|
||||
int PROC insertmacro(char *cmdstr,int count);
|
||||
int PROC join(int count);
|
||||
int PROC killargs(int *argcp,char * * *argvp);
|
||||
int PROC locate(char *pattern,char *linep);
|
||||
int PROC lookup(char c);
|
||||
int PROC macrocommand(void);
|
||||
int PROC makedest(char *str,int start,int ssize,int size);
|
||||
int PROC map(int insert);
|
||||
int PROC match(int p);
|
||||
int PROC max(int a,int b);
|
||||
int PROC min(int a,int b);
|
||||
int PROC move_to_undo(struct undostack *u,int start,int lump);
|
||||
int PROC movearound(char cmd);
|
||||
int PROC moveleft(char *src,char *dest,int length);
|
||||
int PROC moveright(char *src,char *dest,int length);
|
||||
int PROC moveword(int cp,int forwd,int toword);
|
||||
int PROC mvcur(int y,int x);
|
||||
int PROC nextfile(int prev);
|
||||
int PROC nextline(int advance,int dest,int count);
|
||||
int PROC nointr(void);
|
||||
int PROC numtoa(char *str,int num);
|
||||
int PROC ok_to_scroll(int top,int bottom);
|
||||
int PROC oktoedit(int writeold);
|
||||
int PROC omatch(char *pattern,char * *cp,char *endp);
|
||||
int PROC outputf(char *fname);
|
||||
int PROC parse(char *inp);
|
||||
int PROC patsize(char * *pattern);
|
||||
int PROC plural(int num,char *string);
|
||||
int PROC popblock(struct undostack *u);
|
||||
int PROC popmem(struct undostack *u,int start,int size);
|
||||
int PROC popw(struct undostack *u,int *i);
|
||||
int PROC print(void);
|
||||
int PROC printall(void);
|
||||
int PROC printch(char c);
|
||||
int PROC printi(int num);
|
||||
int PROC println(void);
|
||||
int PROC printone(int i);
|
||||
int PROC prints(char *s);
|
||||
int PROC prompt(int toot,char *s);
|
||||
int PROC pushblock(struct undostack *u);
|
||||
int PROC pushmem(struct undostack *u,int start,int size);
|
||||
int PROC pushw(struct undostack *u,int i);
|
||||
int PROC put(int before);
|
||||
int PROC putback(int start,int *newend);
|
||||
int PROC putfile(struct _iobuf *f,int start,int endd);
|
||||
int PROC putin(struct undostack *save_undo,int *curp);
|
||||
int PROC readfile(void);
|
||||
int PROC redisplay(int flag);
|
||||
int PROC refresh(int y,int x,int start,int endd,int rest);
|
||||
int PROC resetX(void);
|
||||
int PROC scan(int length,char tst,char ch,char *src);
|
||||
int PROC scroll(int down);
|
||||
int PROC scrollback(int curr);
|
||||
int PROC scrollforward(int curr);
|
||||
int PROC sentence(int start,int forwd);
|
||||
int PROC setX(int cp);
|
||||
int PROC setY(int cp);
|
||||
int PROC setcmd(void);
|
||||
int PROC setend(void);
|
||||
int PROC setpos(int loc);
|
||||
int PROC settop(int lines);
|
||||
int PROC skip(char *chars,int cp,int step);
|
||||
int PROC skipws(int loc);
|
||||
int PROC squiggle(int endp,char c,int dorepl);
|
||||
int PROC stamp(char *s,char *template);
|
||||
int PROC strput(char *s);
|
||||
int PROC swap(int *a,int *b);
|
||||
int PROC takeout(struct undostack *save_undo,int *curp);
|
||||
int PROC to_index(int line);
|
||||
int PROC to_line(int cp);
|
||||
int PROC toedit(int count);
|
||||
int PROC tow(int cp,int step);
|
||||
int PROC undefine(int i);
|
||||
int PROC unmap(void);
|
||||
int PROC uputcmd(struct undostack *u,int size,int start,char cmd);
|
||||
int PROC version(void);
|
||||
int PROC whatline(void);
|
||||
int PROC wr_stat(void);
|
||||
int PROC writefile(void);
|
||||
int PROC writeline(int y,int x,int start);
|
||||
int PROC zdraw(char code);
|
||||
int PROC zerostack(struct undostack *u);
|
||||
int main(int argc,char * *argv);
|
||||
#endif /*_PROTO_D*/
|
||||
7
src/cmd/levee/readme.os2
Normal file
7
src/cmd/levee/readme.os2
Normal file
@@ -0,0 +1,7 @@
|
||||
If you wish to have your copy of Levee as a family mode application, all
|
||||
you need to do is bind it. It's already set up as a family mode application-
|
||||
there are some small differences for input (dos lv sees ^C and treats it
|
||||
like an ordinary character; os2 lv never sees ^C, because it's eaten by trap
|
||||
handlers) and redirectability (os2 lv uses getch() - a microsoft library
|
||||
function; dos vi uses dos function 0x07 - "get raw character from stdin,
|
||||
whatever that may be") but these shouldn't be a problem.
|
||||
101
src/cmd/levee/rmxcall.c
Normal file
101
src/cmd/levee/rmxcall.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* iRMX interface for levee (Intel C)
|
||||
*/
|
||||
#include "levee.h"
|
||||
#if OS_RMX
|
||||
|
||||
extern char FkL, CurRT, CurLT, CurUP, CurDN;
|
||||
|
||||
extern alien rq$s$write$move();
|
||||
|
||||
strput(s)
|
||||
/* strput: write a string to stdout */
|
||||
char *s;
|
||||
{
|
||||
int dummy;
|
||||
|
||||
if (s)
|
||||
rq$s$write$move(fileno(stdout), s, strlen(s), &dummy);
|
||||
}
|
||||
|
||||
char
|
||||
getKey()
|
||||
/* getKey: read a character from stdin */
|
||||
{
|
||||
char c,sw;
|
||||
unsigned dummy;
|
||||
|
||||
read(0,&c,1);
|
||||
|
||||
if (c == FkL) { /* (single character) function key lead-in */
|
||||
dq$special(3,&fileno(stdin),&dummy); /* grab a raw-mode character */
|
||||
if (read(0,&sw,1) == 1)
|
||||
if (sw == CurLT)
|
||||
c = LTARROW;
|
||||
else if (sw == CurRT)
|
||||
c = RTARROW;
|
||||
else if (sw == CurUP)
|
||||
c = UPARROW;
|
||||
else if (sw == CurDN)
|
||||
c = DNARROW;
|
||||
else
|
||||
c = sw | 0x80;
|
||||
dq$special(1,&fileno(stdin),&dummy); /* back into transparent mode */
|
||||
}
|
||||
#if 0
|
||||
else if (c == 0x7f) /* good old dos kludge... */
|
||||
return erase;
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
|
||||
int max(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a>b)?a:b;
|
||||
}
|
||||
|
||||
int min(a,b)
|
||||
int a,b;
|
||||
{
|
||||
return (a>b)?b:a;
|
||||
}
|
||||
|
||||
extern alien token rq$c$create$command$connection(),
|
||||
rq$c$delete$command$connection(),
|
||||
rq$c$send$command();
|
||||
|
||||
int system(s)
|
||||
/* system: do a shell escape */
|
||||
char *s;
|
||||
{
|
||||
char *string();
|
||||
unsigned cp, error, status, dummy;
|
||||
|
||||
cp = rq$c$create$command$connection(fileno(stdin),fileno(stdout),0,&error);
|
||||
if (!error) {
|
||||
rq$c$send$command(cp,string(s),&status,&error);
|
||||
rq$c$delete$command$connection(cp,&dummy);
|
||||
}
|
||||
return error?(error|0x8000):(status&0x7fff);
|
||||
}
|
||||
#endif
|
||||
32
src/cmd/levee/tc
Normal file
32
src/cmd/levee/tc
Normal file
@@ -0,0 +1,32 @@
|
||||
if (!(ttytype = getenv("TERM"))) {
|
||||
S1("TERM not set");
|
||||
exit(6);
|
||||
}
|
||||
if (tgetent(tc, ttytype) != 1) {
|
||||
sprintf(Msg, "Can't load %s", ttytype);
|
||||
S;
|
||||
exit(7);
|
||||
}
|
||||
ospeed = newmode.c_cflag & CBAUD;
|
||||
LI = tgetnum("li") - 1;
|
||||
CO = tgetnum("co");
|
||||
if (!(s = Tgetstr("pc")))
|
||||
PC = '\0';
|
||||
else
|
||||
PC = *s;
|
||||
|
||||
CD = Tgetstr("cd");
|
||||
CE = Tgetstr("ce");
|
||||
CL = Tgetstr("cl");
|
||||
CM = Tgetstr("cm");
|
||||
SE = Tgetstr("se");
|
||||
SO = Tgetstr("so");
|
||||
#ifdef linux
|
||||
CF = Tgetstr("vi");
|
||||
CN = Tgetstr("ve");
|
||||
#else
|
||||
CF = Tgetstr("CF");
|
||||
CN = Tgetstr("CN");
|
||||
#endif
|
||||
if (CF && !CN)
|
||||
CN = Tgetstr("CO");
|
||||
291
src/cmd/levee/termcap.i
Normal file
291
src/cmd/levee/termcap.i
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#if TERMCAP_EMULATION
|
||||
/*
|
||||
* Termcap handlers
|
||||
*
|
||||
* Routines included:
|
||||
* tc_init() -- set up all the terminal stuff levee will need.
|
||||
* *xtract() -- get a field out of the termcap entry.
|
||||
* *parseit() -- parse a termcap field.
|
||||
* tgoto() -- put a gotoXY string into a buffer.
|
||||
* * -> internal routine.
|
||||
*/
|
||||
|
||||
#if OS_RMX | OS_DOS /* default to ANSI.SYS termcap */
|
||||
char termcap[200] = "Ansi subset:CM=\033[%d;%dH,Y,1,1:\
|
||||
CE=\033[K:CL=\033[H\033[J:LINES=24:COLS=79:HO=\033[H:FkL=\033:\
|
||||
CurR=C:CurL=D:CurU=A:CurD=B";
|
||||
#endif
|
||||
|
||||
char *
|
||||
parseit(ptr,savearea)
|
||||
/* parse a termcap field */
|
||||
char *ptr;
|
||||
char **savearea;
|
||||
{
|
||||
char *p = *savearea;
|
||||
char *op = *savearea;
|
||||
int tmp;
|
||||
|
||||
while (*ptr && *ptr != ':') {
|
||||
if (*ptr == '\\' && ptr[1]) {
|
||||
++ptr;
|
||||
switch (*ptr) {
|
||||
case 'E':
|
||||
*p++ = '\033';
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
tmp = 0;
|
||||
while (*ptr >= '0' && *ptr <= '9')
|
||||
tmp = (tmp*8)+(*ptr++ - '0');
|
||||
*p++ = tmp;
|
||||
--ptr;
|
||||
default:
|
||||
*p++ = *ptr;
|
||||
}
|
||||
}
|
||||
else *p++ = *ptr;
|
||||
++ptr;
|
||||
}
|
||||
*p++ = 0;
|
||||
*savearea = p;
|
||||
return op;
|
||||
} /* parseit */
|
||||
|
||||
char *
|
||||
xtract(ptr,name,savearea)
|
||||
/* get something from the termcap
|
||||
*
|
||||
* arguments: tcentry -- the termcap entry
|
||||
* what -- the field we want to get (NULL means first field)
|
||||
* savearea-- pointer to static buffer for parsed fields.
|
||||
*/
|
||||
char *ptr;
|
||||
char name[];
|
||||
char **savearea;
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
if (!name) /* return first field of entry -- terminal name? */
|
||||
return parseit(ptr,savearea);
|
||||
|
||||
size = strlen(name);
|
||||
/*
|
||||
* always skip the first (terminal name) field
|
||||
*/
|
||||
while (*ptr) {
|
||||
while (*ptr && *ptr != ':') {
|
||||
if (*ptr == '\\')
|
||||
ptr++;
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr)
|
||||
ptr++;
|
||||
if (*ptr && strncmp(name,ptr,size) == 0 && ptr[size] == '=')
|
||||
return parseit(&ptr[1+size],savearea);
|
||||
puts("\r");
|
||||
}
|
||||
return NULL;
|
||||
} /* xtract */
|
||||
|
||||
char
|
||||
charext(tc,what,savearea)
|
||||
/* get a character field from the termcap */
|
||||
char *tc, *what, **savearea;
|
||||
{
|
||||
char *p = xtract(tc,what,savearea);
|
||||
if (p)
|
||||
return *p;
|
||||
return 0;
|
||||
} /* charext */
|
||||
|
||||
/* internal variables just for termcap */
|
||||
static int _Xfirst, _xpad, _ypad;
|
||||
|
||||
void
|
||||
tc_init()
|
||||
/* get the termcap stuff and go berserk parsing it */
|
||||
/* if anything horrid goes wrong, levee will crash */
|
||||
{
|
||||
#if OS_RMX
|
||||
char *p = termcap;
|
||||
#else
|
||||
char *getenv();
|
||||
char *p = getenv("TERMCAP");
|
||||
#endif
|
||||
char *lp, *ptr;
|
||||
|
||||
#if OS_DOS
|
||||
if (!p)
|
||||
p = termcap;
|
||||
#endif
|
||||
#if !(OS_RMX|OS_DOS)
|
||||
if (!p) {
|
||||
puts("lv: no termcap\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
lp = Malloc(strlen(p)+1);
|
||||
if (!lp) {
|
||||
puts("lv: out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
TERMNAME = xtract(p,NULL,&lp);
|
||||
CM = xtract(p,"CM",&lp);
|
||||
HO = xtract(p,"HO",&lp);
|
||||
UP = xtract(p,"UP",&lp);
|
||||
CE = xtract(p,"CE",&lp);
|
||||
CL = xtract(p,"CL",&lp);
|
||||
BELL = xtract(p,"BELL",&lp);
|
||||
if (!BELL)
|
||||
BELL = "\007";
|
||||
OL = xtract(p,"OL",&lp);
|
||||
UpS = xtract(p,"UpS",&lp);
|
||||
CURon= xtract(p,"CURon",&lp);
|
||||
CURoff=xtract(p,"CURoff",&lp);
|
||||
|
||||
FkL = charext(p,"FkL",&lp);
|
||||
CurRT= charext(p,"CurR",&lp);
|
||||
CurLT= charext(p,"CurL",&lp);
|
||||
CurUP= charext(p,"CurU",&lp);
|
||||
CurDN= charext(p,"CurD",&lp);
|
||||
|
||||
canUPSCROLL = (UpS != NULL);
|
||||
CA = (CM != NULL);
|
||||
|
||||
if ((LINES=atoi(ptr=xtract(p,"LINES",&lp))) <= 0) {
|
||||
puts("lv: bad termcap");
|
||||
exit(1);
|
||||
}
|
||||
dofscroll = LINES/2;
|
||||
if ((COLS=atoi(ptr=xtract(p,"COLS",&lp))-1) <= 0 || COLS >= MAXCOLS) {
|
||||
puts("lv: bad termcap");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_ypad = _xpad = 0;
|
||||
_Xfirst = 1;
|
||||
|
||||
p = CM;
|
||||
|
||||
while (*p && *p != ',')
|
||||
p++;
|
||||
if (!*p)
|
||||
return;
|
||||
*p++ = 0;
|
||||
if (*p != ',')
|
||||
_Xfirst = (*p++ == 'X');
|
||||
if (!*p)
|
||||
return;
|
||||
++p;
|
||||
while (*p && *p != ',')
|
||||
_xpad = (_xpad*10) + (*p++ - '0');
|
||||
if (!*p)
|
||||
return;
|
||||
++p;
|
||||
while (*p)
|
||||
_ypad = (_ypad*10) + (*p++ - '0');
|
||||
}
|
||||
|
||||
#define tgoto(s,y,x) (_Xfirst?sprintf(s,CM,x+_xpad,y+_ypad):\
|
||||
sprintf(s,CM,y+_ypad,x+_xpad))
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_TERMCAP_H
|
||||
# include <termcap.h>
|
||||
#else
|
||||
# include <term.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
void
|
||||
tc_init()
|
||||
/* read in the termcap entry for this terminal.
|
||||
*/
|
||||
{
|
||||
static char tcbuf[2048+1024];
|
||||
char *bufp;
|
||||
char *term = getenv("TERM");
|
||||
|
||||
if (( term ? tgetent(tcbuf, term) : 0) != 0) {
|
||||
TERMNAME = term;
|
||||
bufp = tcbuf + 2048;
|
||||
CM = tgetstr("cm", &bufp);
|
||||
UP = tgetstr("up", &bufp);
|
||||
HO = tgetstr("ho", &bufp);
|
||||
if (!HO) {
|
||||
char *goto0 = tgoto(CM, 0, 0);
|
||||
|
||||
if (goto0)
|
||||
HO = strdup(goto0);
|
||||
}
|
||||
|
||||
CL = tgetstr("cl", &bufp);
|
||||
CE = tgetstr("ce", &bufp);
|
||||
BELL = tgetstr("vb", &bufp);
|
||||
if (!BELL)
|
||||
BELL = "\007";
|
||||
OL = tgetstr("al", &bufp);
|
||||
UpS = tgetstr("sr", &bufp);
|
||||
CURon = tgetstr("ve", &bufp);
|
||||
CURoff = tgetstr("vi", &bufp);
|
||||
|
||||
LINES = tgetnum("li");
|
||||
COLS = tgetnum("co");
|
||||
|
||||
/* don't trust li & co, because we might actually
|
||||
* be on a console or gui instead of the tinned
|
||||
* tty that termcap expects
|
||||
*/
|
||||
#if defined(TIOCGSIZE)
|
||||
{ struct ttysize tty;
|
||||
if (ioctl(0, TIOCGSIZE, &tty) == 0) {
|
||||
if (tty.ts_lines) LINES=tty.ts_lines;
|
||||
if (tty.ts_cols) COLS=tty.ts_cols;
|
||||
}
|
||||
}
|
||||
#elif defined(TIOCGWINSZ)
|
||||
{ struct winsize tty;
|
||||
if (ioctl(0, TIOCGWINSZ, &tty) == 0) {
|
||||
if (tty.ws_row) LINES=tty.ws_row;
|
||||
if (tty.ws_col) COLS=tty.ws_col;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dofscroll = LINES/2;
|
||||
|
||||
/* set cursor movement keys to zero for now */
|
||||
FkL = CurRT = CurLT = CurUP = CurDN = EOF;
|
||||
|
||||
canUPSCROLL = (UpS != NULL);
|
||||
CA = (CM != NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
86
src/cmd/levee/ucsd.c
Normal file
86
src/cmd/levee/ucsd.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifndef moveleft
|
||||
|
||||
VOID PROC
|
||||
moveleft(src,dest,length)
|
||||
register char *src,*dest;
|
||||
register int length;
|
||||
{
|
||||
while (--length >= 0)
|
||||
*(dest++) = *(src++);
|
||||
}
|
||||
|
||||
#endif /*moveleft*/
|
||||
|
||||
#ifndef moveright
|
||||
|
||||
VOID PROC
|
||||
moveright(src,dest,length)
|
||||
register char *src,*dest;
|
||||
register int length;
|
||||
{
|
||||
src = &src[length];
|
||||
dest = &dest[length];
|
||||
while (--length >= 0)
|
||||
*(--dest) = *(--src);
|
||||
}
|
||||
|
||||
#endif /*moveright*/
|
||||
|
||||
#ifndef fillchar
|
||||
|
||||
VOID PROC
|
||||
fillchar(src,length,ch)
|
||||
register char *src,ch;
|
||||
register int length;
|
||||
{
|
||||
while (--length >= 0)
|
||||
*(src++) = ch;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int PROC
|
||||
scan(length,tst,ch,src)
|
||||
int length;
|
||||
register char tst,ch,*src;
|
||||
{
|
||||
register int inc,l;
|
||||
|
||||
if (length < 0)
|
||||
inc = -1;
|
||||
else
|
||||
inc = 1;
|
||||
if (tst == '!') {
|
||||
for(l = ((int)inc)*length; l > 0; l--,src += (long)inc)
|
||||
if (*src != ch)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
for(l = ((int)inc)*length; l > 0; l--,src += (long)inc)
|
||||
if (*src == ch)
|
||||
break;
|
||||
}
|
||||
return length-(inc*l);
|
||||
}
|
||||
272
src/cmd/levee/undo.c
Normal file
272
src/cmd/levee/undo.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define BUFSZ sizeof(undo.coreblock)
|
||||
#define AVAIL(x) ((x)<<1)
|
||||
#define INDEX(x) ((1+x)>>1)
|
||||
|
||||
bool PROC
|
||||
pushblock(u)
|
||||
struct undostack *u;
|
||||
{
|
||||
if (u->blockp == 0)
|
||||
if ((uwrite = OPEN_NEW(undobuf)) < 0)
|
||||
return FALSE;
|
||||
if (BUFSZ == WRITE_TEXT(uwrite, u->coreblock, BUFSZ)) {
|
||||
u->blockp++;
|
||||
u->ptr = 0;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
pushw(u, i)
|
||||
struct undostack *u;
|
||||
int i;
|
||||
{
|
||||
if (u->ptr >= PAGESIZE && !pushblock(u))
|
||||
return FALSE;
|
||||
u->coreblock[u->ptr++] = i;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
pushmem(u, start, size)
|
||||
struct undostack *u;
|
||||
int start,size;
|
||||
{
|
||||
int chunk;
|
||||
bool ok;
|
||||
|
||||
ok = TRUE;
|
||||
while (ok && size > 0) {
|
||||
chunk = min(size, AVAIL(PAGESIZE-u->ptr));
|
||||
moveleft(&core[start], (char*)&u->coreblock[u->ptr], chunk);
|
||||
size -= chunk;
|
||||
start += chunk;
|
||||
if (size > 0)
|
||||
ok = pushblock(u);
|
||||
else
|
||||
u->ptr += INDEX(chunk);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
zerostack(u)
|
||||
struct undostack *u;
|
||||
{
|
||||
if (u->blockp > 0)
|
||||
CLOSE_FILE(uwrite);
|
||||
u->blockp = 0; /* initialize the stack */
|
||||
u->ptr = 0;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
uputcmd(u, size, start, cmd)
|
||||
struct undostack *u;
|
||||
int size,start;
|
||||
char cmd;
|
||||
{
|
||||
return(pushw(u, size) && pushw(u, start) && pushw(u, cmd));
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
insert_to_undo(u, start, size)
|
||||
struct undostack *u;
|
||||
int start,size;
|
||||
{
|
||||
if (uputcmd(u, size, start, U_DELC)) {
|
||||
fixmarkers(start, size);
|
||||
bufmax += size;
|
||||
}
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
/* delete stuff from the buffer && put it into the undo stack */
|
||||
|
||||
bool PROC
|
||||
delete_to_undo(u, start, lump)
|
||||
struct undostack *u;
|
||||
int start, lump;
|
||||
{
|
||||
if (lump <= 0)
|
||||
return TRUE;
|
||||
else if (pushmem(u,start,lump) && uputcmd(u,lump,start,U_ADDC)) {
|
||||
moveleft(&core[start+lump], &core[start], bufmax-(start+lump));
|
||||
bufmax -= lump;
|
||||
fixmarkers(start,-lump);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy stuff into the undo buffer */
|
||||
|
||||
bool PROC
|
||||
move_to_undo(u, start, lump)
|
||||
struct undostack *u;
|
||||
int start,lump;
|
||||
{
|
||||
return pushmem(u, start, lump) && uputcmd(u,lump,start,U_MOVEC);
|
||||
}
|
||||
|
||||
bool PROC
|
||||
popblock(u)
|
||||
struct undostack *u;
|
||||
{
|
||||
if (u->blockp > 0) {
|
||||
if (SEEK_POSITION(uread, (long)((--u->blockp)*BUFSZ), 0) < 0)
|
||||
return FALSE;
|
||||
if (BUFSZ == READ_TEXT(uread, u->coreblock, BUFSZ)) {
|
||||
u->ptr = PAGESIZE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
popw(u, i)
|
||||
struct undostack *u;
|
||||
int *i;
|
||||
{
|
||||
if (u->ptr < 1 && !popblock(u))
|
||||
return FALSE;
|
||||
*i = u->coreblock[--u->ptr];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool PROC
|
||||
popmem(u, start, size)
|
||||
struct undostack *u;
|
||||
int start, size;
|
||||
{
|
||||
int chunk, loc;
|
||||
bool ok;
|
||||
|
||||
loc = start+size; /* running backwards */
|
||||
ok = TRUE;
|
||||
while (ok && size > 0) {
|
||||
chunk = min(size, AVAIL(u->ptr));
|
||||
size -= chunk;
|
||||
loc -= chunk;
|
||||
moveleft((char*)&u->coreblock[u->ptr-INDEX(chunk)], &core[loc], chunk);
|
||||
if (size > 0)
|
||||
ok = popblock(u);
|
||||
else
|
||||
u->ptr -= INDEX(chunk);
|
||||
}
|
||||
return(ok);
|
||||
}
|
||||
|
||||
/* delete (I)nserted text */
|
||||
|
||||
bool PROC
|
||||
takeout(save_undo,curp)
|
||||
struct undostack *save_undo;
|
||||
int *curp;
|
||||
{
|
||||
int lump;
|
||||
|
||||
return popw(&undo,curp) && popw(&undo,&lump)
|
||||
&& delete_to_undo(save_undo,*curp,lump);
|
||||
}
|
||||
|
||||
bool PROC
|
||||
copyover(save_undo,curp)
|
||||
struct undostack *save_undo;
|
||||
int *curp;
|
||||
{
|
||||
int lump;
|
||||
|
||||
return popw(&undo, curp) && popw(&undo, &lump)
|
||||
&& move_to_undo(save_undo, *curp, lump)
|
||||
&& popmem(&undo, *curp, lump);
|
||||
}
|
||||
|
||||
bool PROC
|
||||
putin(save_undo,curp)
|
||||
struct undostack *save_undo;
|
||||
int *curp;
|
||||
{
|
||||
int lump;
|
||||
|
||||
if (popw(&undo,curp) && popw(&undo,&lump) && (bufmax+lump < SIZE)) {
|
||||
insert_to_undo(save_undo, *curp, lump);
|
||||
moveright(&core[*curp], &core[*curp+lump], bufmax-*curp);
|
||||
if (popmem(&undo, *curp, lump))
|
||||
return TRUE;
|
||||
else
|
||||
moveleft(&core[*curp+lump], &core[*curp], bufmax-*curp);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* driver for undo -- returns last address modified || -1 if error */
|
||||
|
||||
int PROC
|
||||
fixcore(topp)
|
||||
int *topp;
|
||||
{
|
||||
int curp;
|
||||
static struct undostack save_undo;
|
||||
bool closeio, ok;
|
||||
int cch;
|
||||
|
||||
if (undo.blockp > 0 || undo.ptr > 0) {
|
||||
closeio = (undo.blockp > 0);
|
||||
if (closeio) { /* save diskfile */
|
||||
CLOSE_FILE(uwrite); /* close current undo file */
|
||||
rename(undobuf,undotmp);
|
||||
uread = OPEN_OLD(undotmp); /* reopen it for reading */
|
||||
if (uread < 0)
|
||||
return -1;
|
||||
}
|
||||
*topp = SIZE+1;
|
||||
curp = -MAGICNUMBER;
|
||||
save_undo.blockp = save_undo.ptr = 0;
|
||||
ok = TRUE;
|
||||
while (ok && popw(&undo,&cch)) {
|
||||
switch (cch) {
|
||||
case U_ADDC : ok = putin(&save_undo, &curp); break;
|
||||
case U_MOVEC: ok = copyover(&save_undo, &curp); break;
|
||||
case U_DELC : ok = takeout(&save_undo, &curp); break;
|
||||
}
|
||||
if (curp < *topp)
|
||||
*topp = curp;
|
||||
}
|
||||
if (curp >= 0)
|
||||
undo = save_undo;
|
||||
if (closeio) {
|
||||
CLOSE_FILE(uread); /* Zap old buffer */
|
||||
unlink(undotmp);
|
||||
}
|
||||
if (!ok)
|
||||
error();
|
||||
return(curp);
|
||||
}
|
||||
return ERR;
|
||||
}
|
||||
200
src/cmd/levee/unixcall.c
Normal file
200
src/cmd/levee/unixcall.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* Unix interface for levee
|
||||
*/
|
||||
#include "levee.h"
|
||||
|
||||
#ifdef OS_UNIX
|
||||
|
||||
#include "extern.h"
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int
|
||||
min(a,b)
|
||||
int a, b;
|
||||
{
|
||||
return (a>b) ? b : a;
|
||||
}
|
||||
|
||||
int
|
||||
max(a,b)
|
||||
int a, b;
|
||||
{
|
||||
return (a<b) ? b : a;
|
||||
}
|
||||
|
||||
void strput(s)
|
||||
char *s;
|
||||
{
|
||||
if (s)
|
||||
write(1, s, strlen(s));
|
||||
}
|
||||
|
||||
#if !HAVE_BASENAME
|
||||
char *
|
||||
basename(s)
|
||||
char *s;
|
||||
{
|
||||
char *rindex();
|
||||
char *p;
|
||||
|
||||
if (p=strrchr(s,'/'))
|
||||
return 1+p;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ioset = 0;
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
|
||||
#if !HAVE_TCGETATTR
|
||||
#define tcgetattr(fd,t) ioctl(fd, TCGETS, t)
|
||||
#define tcsetattr(fd,n,t) ioctl(fd, n, t)
|
||||
#define TCSANOW TCSETAF
|
||||
#endif
|
||||
|
||||
static struct termios old;
|
||||
|
||||
void
|
||||
initcon()
|
||||
{
|
||||
struct termios new;
|
||||
|
||||
if (!ioset) {
|
||||
tcgetattr(0, &old); /* get editing keys */
|
||||
|
||||
Erasechar = old.c_cc[VERASE];
|
||||
eraseline = old.c_cc[VKILL];
|
||||
|
||||
new = old;
|
||||
|
||||
new.c_iflag &= ~(IXON|IXOFF|IXANY|ICRNL|INLCR);
|
||||
new.c_lflag &= ~(ICANON|ISIG|ECHO);
|
||||
new.c_oflag = 0;
|
||||
|
||||
tcsetattr(0, TCSANOW, &new);
|
||||
ioset=1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fixcon()
|
||||
{
|
||||
if (ioset) {
|
||||
tcsetattr(0, TCSANOW, &old);
|
||||
ioset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* HAVE_TERMIOS_H */
|
||||
|
||||
static struct sgttyb old;
|
||||
static struct tchars oldtchars;
|
||||
static struct ltchars oldltchars;
|
||||
|
||||
void
|
||||
initcon()
|
||||
{
|
||||
struct tchars new_tc;
|
||||
struct ltchars new_ltc;
|
||||
struct sgttyb new;
|
||||
|
||||
if (!ioset) {
|
||||
ioctl(0, TIOCGETC, &oldtchars);
|
||||
ioctl(0, TIOCGLTC, &oldltchars);
|
||||
|
||||
/* get editing keys */
|
||||
Erasechar = 0177;
|
||||
eraseline = 'U' & 037;
|
||||
|
||||
new_tc = oldtchars;
|
||||
new_tc.t_eofc = -1; /* end-of-file */
|
||||
new_tc.t_quitc = -1; /* quit */
|
||||
new_tc.t_intrc = -1; /* interrupt */
|
||||
new_ltc = oldltchars;
|
||||
new_ltc.t_suspc = -1; /* stop process */
|
||||
new_ltc.t_dsuspc = -1; /* delayed stop process */
|
||||
new_ltc.t_rprntc = -1; /* reprint line */
|
||||
new_ltc.t_flushc = -1; /* flush output */
|
||||
new_ltc.t_werasc = -1; /* word erase */
|
||||
new_ltc.t_lnextc = -1; /* literal next character */
|
||||
ioctl(0, TIOCSETC, &new_tc);
|
||||
ioctl(0, TIOCSLTC, &new_ltc);
|
||||
|
||||
ioctl(0, TIOCGETP, &old);
|
||||
new = old;
|
||||
|
||||
new.sg_flags &= ~(ECHO | CRMOD | XTABS | RAW);
|
||||
new.sg_flags |= CBREAK;
|
||||
|
||||
ioctl(0, TIOCSETP, &new);
|
||||
ioset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fixcon()
|
||||
{
|
||||
if (ioset) {
|
||||
ioctl(0, TIOCSETP, &old);
|
||||
ioctl(0, TIOCSETC, &oldtchars);
|
||||
ioctl(0, TIOCSLTC, &oldltchars);
|
||||
ioset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_TERMIOS_H */
|
||||
|
||||
int
|
||||
getKey()
|
||||
{
|
||||
unsigned char c[1];
|
||||
fd_set input;
|
||||
|
||||
fflush(stdout);
|
||||
/* we're using Unix select() to wait for input, so lets hope that
|
||||
* all the Unices out there support select(). If your Unix doesn't,
|
||||
* you can make this work by replacing this select loop with:
|
||||
*
|
||||
* while (read(0,c,1) != 1)
|
||||
* ;
|
||||
* return c[1];
|
||||
*
|
||||
* ... and watch your load-average peg.
|
||||
*/
|
||||
while (1) {
|
||||
FD_ZERO(&input);
|
||||
FD_SET(0, &input);
|
||||
|
||||
select(1, &input, 0, 0, 0);
|
||||
if( read(0,c,1) == 1)
|
||||
return c[0];
|
||||
};
|
||||
}
|
||||
#endif
|
||||
1
src/cmd/levee/version.c
Normal file
1
src/cmd/levee/version.c
Normal file
@@ -0,0 +1 @@
|
||||
char codeversion[] = VERSION;
|
||||
109
src/cmd/levee/wildargs.c
Normal file
109
src/cmd/levee/wildargs.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* LEVEE, or Captain Video; A vi clone
|
||||
*
|
||||
* Copyright (c) 1982-2007 David L Parsons
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, without or
|
||||
* without modification, are permitted provided that the above
|
||||
* copyright notice and this paragraph are duplicated in all such
|
||||
* forms and that any documentation, advertising materials, and
|
||||
* other materials related to such distribution and use acknowledge
|
||||
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
|
||||
* My name may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* wildcard filename expanders for levee.
|
||||
*/
|
||||
#include "levee.h"
|
||||
#include "extern.h"
|
||||
|
||||
#if OS_UNIX
|
||||
# include <stdlib.h>
|
||||
#elif !OS_RMX
|
||||
# include <glob.h>
|
||||
#endif
|
||||
|
||||
|
||||
int wilderr, wildcard;
|
||||
|
||||
int PROC
|
||||
expandargs(name, argcp, argvp)
|
||||
char *name;
|
||||
int *argcp;
|
||||
char ***argvp;
|
||||
{
|
||||
#if OS_RMX|OS_UNIX
|
||||
wilderr = doaddwork(name, argcp, argvp) < 0;
|
||||
#else
|
||||
register char *p;
|
||||
|
||||
wilderr = 0;
|
||||
|
||||
if (p=glob(name, (char*)0)) {
|
||||
do {
|
||||
if (doaddwork(p, argcp, argvp) < 0) {
|
||||
wilderr++;
|
||||
break;
|
||||
}
|
||||
} while (p=glob((char*)0, (char*)0));
|
||||
}
|
||||
else if (doaddwork(name, argcp, argvp) < 0)
|
||||
wilderr++;
|
||||
#endif /*!OS_RMX*/
|
||||
if (wilderr)
|
||||
killargs(argcp, argvp);
|
||||
return !wilderr;
|
||||
}
|
||||
|
||||
#define QUANTUM 10
|
||||
|
||||
int PROC
|
||||
doaddwork(token,argcp,argvp)
|
||||
char *token;
|
||||
int *argcp;
|
||||
char ***argvp;
|
||||
{
|
||||
char **ap = *argvp;
|
||||
int ac = *argcp;
|
||||
int size;
|
||||
|
||||
if ( ac%QUANTUM == 0) { /* realloc more memory! */
|
||||
size = (QUANTUM+ac)*sizeof(char**);
|
||||
ap = (ac == 0)?malloc(size):realloc(ap, size);
|
||||
if (!ap) {
|
||||
*argcp = 0;
|
||||
goto memfail;
|
||||
}
|
||||
}
|
||||
if ( (ap[ac] = strdup(token)) ) {
|
||||
#if OS_ATARI|OS_RMX|OS_FLEXOS
|
||||
strlwr(ap[ac]); /* monocase filesystem */
|
||||
#endif
|
||||
*argvp = ap;
|
||||
return (*argcp)++;
|
||||
}
|
||||
memfail:
|
||||
errmsg("no memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
VOID PROC
|
||||
killargs(argcp, argvp)
|
||||
int *argcp;
|
||||
char ***argvp;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=(*argcp)-1; i >= 0; i--)
|
||||
free((*argvp)[i]);
|
||||
if (*argcp)
|
||||
free(*argvp);
|
||||
*argcp = 0;
|
||||
*argvp = 0L;
|
||||
}
|
||||
Reference in New Issue
Block a user