1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-24 10:06:30 -05:00

Compare commits

..

No commits in common. "50b727bf7ffe7d6152c067c989e193882d3ac409" and "893e34b74063e7cecdabf6ef39e5dfeeb678d785" have entirely different histories.

32 changed files with 2330 additions and 2102 deletions

511
basic.c
View File

@ -1,16 +1,19 @@
/* basic.c -- implements basic.h */ /* basic.c -- implements basic.h */
#include "basic.h" #include "basic.h"
/* The routines in this file move the cursor around on the screen. They /* basic.c
compute a new value for the cursor, then adjust ".". The display code *
always updates the cursor location, so only moves between lines, or * The routines in this file move the cursor around on the screen. They
functions that adjust the top line in the window and invalidate the * compute a new value for the cursor, then adjust ".". The display code
framing, are hard. * always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
modified by Petri Kutvonen * framing, are hard.
*
* modified by Petri Kutvonen
*/ */
#include <assert.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "input.h" #include "input.h"
@ -19,302 +22,340 @@
#include "terminal.h" #include "terminal.h"
#include "window.h" #include "window.h"
#define CVMVAS 1 /* arguments to page forward/back in pages */
int overlap = 0 ; /* $overlap: line overlap in forw/back page */ #define CVMVAS 1 /* arguments to page forward/back in pages */
int curgoal ; /* $target: column goal for C-P, C-N */
/* This routine, given a pointer to a struct line, and the current cursor int overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */
goal column, return the best choice for the offset. The offset is int curgoal ; /* Goal for C-P, C-N */
returned. Used by "C-N" and "C-P".
/*
* This routine, given a pointer to a struct line, and the current cursor goal
* column, return the best choice for the offset. The offset is returned.
* Used by "C-N" and "C-P".
*/ */
static unsigned getgoal( line_p dlp) { static unsigned getgoal( line_p dlp) {
int col = 0 ; int col ;
const unsigned len = llength( dlp) ; unsigned idx ;
unsigned idx = 0 ; const unsigned len = llength( dlp) ;
while( idx < len) {
unicode_t c ;
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
/* Take tabs, ^X and \xx hex characters into account */ col = 0 ;
if( c == '\t') idx = 0 ;
col += tabwidth - col % tabwidth ; while( idx < len) {
else if( c < 0x20 || c == 0x7F) /* ^x */ unicode_t c ;
col += 2 ; unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
else if( c >= 0x80 && c <= 0xA0) /* \xx */
col += 3 ;
else {
int w = utf8_width( c) ; /* work around */
col += (w < 0) ? 2 : w ; /* unknown unicode width as \u */
}
if( col > curgoal) /* Take tabs, ^X and \xx hex characters into account */
break ; if( c == '\t')
else col += tabwidth - col % tabwidth ;
idx += width ; else if( c < 0x20 || c == 0x7F)
} col += 2 ;
else if( c >= 0x80 && c <= 0xA0)
col += 3 ;
else
col += 1 ;
return idx ; if( col > curgoal)
break ;
idx += width ;
}
return idx ;
} }
/*
/* Move the cursor to the beginning of the current line of active window. */ * Move the cursor to the beginning of the current line of active window.
TBINDABLE( gotobol) {
curwp->w_doto = 0 ;
return TRUE ;
}
/* Move the cursor to the end of the current line of active window. */
TBINDABLE( gotoeol) {
curwp->w_doto = llength( curwp->w_dotp) ;
return TRUE ;
}
/* Goto the beginning of the buffer. Massive adjustment of dot. This is
considered to be hard motion; it really isn't if the original value of
dot is the same as the new value of dot. Normally bound to "M-<".
*/ */
TBINDABLE( gotobob) { boolean gotobol( int f, int n) {
curwp->w_dotp = lforw( curbp->b_linep) ; curwp->w_doto = 0 ;
curwp->w_doto = 0 ; return TRUE ;
curwp->w_flag |= WFHARD ;
return TRUE ;
} }
/*
/* Move to the end of the buffer. Dot is always put at the end of the file * Move the cursor to the end of the current line of active window.
(ZJ). The standard screen code does most of the hard parts of update.
Bound to "M->".
*/ */
TBINDABLE( gotoeob) { boolean gotoeol( int f, int n) {
curwp->w_dotp = curbp->b_linep ; curwp->w_doto = llength( curwp->w_dotp) ;
curwp->w_doto = 0 ; return TRUE ;
curwp->w_flag |= WFHARD ;
return TRUE ;
} }
/*
/* Move forward by full lines. If the number of lines to move is less than * Goto the beginning of the buffer. Massive adjustment of dot. This is
zero, call the backward line function to actually do it. The last * considered to be hard motion; it really isn't if the original value of dot
command controls how the goal column is set. Bound to "C-N". No errors * is the same as the new value of dot. Normally bound to "M-<".
are possible.
*/ */
BBINDABLE( forwline) { boolean gotobob( int f, int n) {
assert( f == TRUE || n == 1) ; curwp->w_dotp = lforw( curbp->b_linep) ;
curwp->w_doto = 0 ;
/* if the last command was not a line move, reset the goal column */ curwp->w_flag |= WFHARD ;
if( (lastflag & CFCPCN) == 0) return TRUE ;
curgoal = getccol( FALSE) ;
/* flag this command as a line move */
thisflag |= CFCPCN ;
/* and move the point down */
if( n) {
line_p dlp = curwp->w_dotp ;
if( n > 0)
while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ;
n -= 1 ;
}
else {
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n += 1 ;
}
}
/* resetting the current position */
curwp->w_dotp = dlp ;
curwp->w_doto = getgoal( dlp) ;
curwp->w_flag |= WFMOVE ;
}
return (n == 0) ? TRUE : FALSE ;
} }
/*
/* This function is like "forwline", but goes backwards. The scheme is * Move to the end of the buffer. Dot is always put at the end of the file
exactly the same. Check for arguments that are less than zero and call * (ZJ). The standard screen code does most of the hard parts of update.
your alternate. Figure out the new line and call "movedot" to perform * Bound to "M->".
the motion. No errors are possible. Bound to "C-P".
*/ */
BBINDABLE( backline) { boolean gotoeob( int f, int n) {
assert( f == TRUE || n == 1) ; curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ;
return forwline( TRUE, -n) ; curwp->w_flag |= WFHARD ;
return TRUE ;
} }
/*
* Move forward by full lines. If the number of lines to move is less than
* zero, call the backward line function to actually do it. The last command
* controls how the goal column is set. Bound to "C-N". No errors are
* possible.
*/
boolean forwline( int f, int n) {
line_p dlp ;
/* Move to a particular line. if (n < 0)
return backline(f, -n);
/* if we are on the last line as we start....fail the command */
if (curwp->w_dotp == curbp->b_linep)
return FALSE;
/* if the last command was not a line move, reset the goal column */
if ((lastflag & CFCPCN) == 0)
curgoal = getccol(FALSE);
/* flag this command as a line move */
thisflag |= CFCPCN;
/* and move the point down */
dlp = curwp->w_dotp;
while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ;
n -= 1 ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/*
* This function is like "forwline", but goes backwards. The scheme is exactly
* the same. Check for arguments that are less than zero and call your
* alternate. Figure out the new line and call "movedot" to perform the
* motion. No errors are possible. Bound to "C-P".
*/
boolean backline( int f, int n) {
line_p dlp ;
if (n < 0)
return forwline(f, -n);
/* if we are on the first line as we start....fail the command */
if (lback(curwp->w_dotp) == curbp->b_linep)
return FALSE;
/* if the last command was not a line move, reset the goal column */
if ((lastflag & CFCPCN) == 0)
curgoal = getccol(FALSE);
/* flag this command as a line move */
thisflag |= CFCPCN;
/* and move the point up */
dlp = curwp->w_dotp;
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n -= 1 ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/*
* Move to a particular line.
* *
* @n: The specified line position at the current buffer. * @n: The specified line position at the current buffer.
*/ */
BINDABLE( gotoline) { int gotoline( int f, int n) {
/* Get an argument if one doesn't exist. */ /* Get an argument if one doesnt exist. */
if( f == FALSE) { if( f == FALSE) {
char *arg ; /* Buffer to hold argument. */ int status ;
char *arg ; /* Buffer to hold argument. */
int status = newmlarg( &arg, "goto-line: ", 0) ; status = newmlarg( &arg, "Line to GOTO: ", 0) ;
if( status != TRUE) if( status != TRUE) {
return status ; mloutstr( "(Aborted)") ;
return status ;
}
n = atoi( arg) ; n = atoi( arg) ;
free( arg) ; free( arg) ;
f = TRUE ; }
}
/* Handle the case where the user may be passed something like this: /* Handle the case where the user may be passed something like this:
* ue filename + * em filename +
* In this case we just go to the end of the buffer. * In this case we just go to the end of the buffer.
*/ */
if( n == 0) if (n == 0)
return gotoeob( f, n) ; return gotoeob(f, n);
/* If a bogus argument was passed, then returns false. */ /* If a bogus argument was passed, then returns false. */
if( n < 0) if (n < 0)
return FALSE ; return FALSE;
/* First, we go to the begin of the buffer. */ /* First, we go to the begin of the buffer. */
gotobob( f, n) ; gotobob(f, n);
return (n == 1) ? TRUE : forwline( TRUE, n - 1) ; return (n == 1) ? TRUE : forwline( f, n - 1) ;
} }
/*
/* Scroll forward by a specified number of lines, or by a full page if no * Scroll forward by a specified number of lines, or by a full page if no
argument. Bound to "C-V". The "2" in the arithmetic on the window size * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
is the overlap; this value is the default overlap value in ITS EMACS. * the overlap; this value is the default overlap value in ITS EMACS. Because
Because this zaps the top line in the display window, we have to do a * this zaps the top line in the display window, we have to do a hard update.
hard update.
*/ */
TBINDABLE( forwpage) { boolean forwpage( int f, int n) {
line_p lp ; line_p lp ;
if( f == FALSE) { if (f == FALSE) {
#if SCROLLCODE #if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll == FALSE */ if (term.t_scroll != NULL) /* $scroll == FALSE */
if (overlap == 0) /* $overlap == 0 */ if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ; n = curwp->w_ntrows * 2 / 3 ;
else else
n = curwp->w_ntrows - overlap; n = curwp->w_ntrows - overlap;
else else
#endif #endif
n = curwp->w_ntrows - 2; /* Default scroll. */ n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Forget the overlap. */ if (n <= 0) /* Forget the overlap. */
n = 1; /* If tiny window. */ n = 1; /* If tiny window. */
} else if( n < 0) } else if (n < 0)
return backpage( f, -n) ; return backpage(f, -n);
#if CVMVAS #if CVMVAS
else /* Convert from pages. */ else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */ n *= curwp->w_ntrows; /* To lines. */
#endif #endif
lp = curwp->w_dotp ; /* lp = curwp->w_linep; */
while( n && lp != curbp->b_linep) { lp = curwp->w_dotp ;
lp = lforw( lp) ; while( n && lp != curbp->b_linep) {
n -= 1 ; lp = lforw( lp) ;
} n -= 1 ;
}
curwp->w_dotp = lp ; /* curwp->w_linep = lp; */
curwp->w_doto = 0 ; curwp->w_dotp = lp;
reposition( TRUE, 0) ; /* center at dot, always succeed */ curwp->w_doto = 0;
reposition( TRUE, 0) ;
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS; curwp->w_flag |= WFHARD | WFKILLS;
#else #else
curwp->w_flag |= WFHARD; curwp->w_flag |= WFHARD;
#endif #endif
return TRUE ; return TRUE;
} }
/*
/* This command is like "forwpage", but it goes backwards. The "2", like * This command is like "forwpage", but it goes backwards. The "2", like
above, is the overlap between the two windows. The value is from the * above, is the overlap between the two windows. The value is from the ITS
ITS EMACS manual. Bound to "M-V". We do a hard update for exactly the * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
same reason. * reason.
*/ */
TBINDABLE( backpage) { boolean backpage( int f, int n) {
line_p lp ; line_p lp ;
if( f == FALSE) { /* interactive, default n = 1 supplied */ if (f == FALSE) { /* interactive, default n = 1 supplied */
/* in interactive mode, first move dot to top of window */ /* in interactive mode, first move dot to top of window */
if( curwp->w_dotp != curwp->w_linep) { if( curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = curwp->w_linep ; curwp->w_dotp = curwp->w_linep ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
/* curwp->w_flag |= WFMOVE ; */ /* curwp->w_flag |= WFMOVE ; */
return TRUE ; return TRUE ;
} }
#if SCROLLCODE #if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll != FALSE */ if (term.t_scroll != NULL) /* $scroll != FALSE */
if (overlap == 0) /* $overlap == 0 */ if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ; n = curwp->w_ntrows * 2 / 3 ;
else else
n = curwp->w_ntrows - overlap; n = curwp->w_ntrows - overlap;
else else
#endif #endif
n = curwp->w_ntrows - 2; /* Default scroll. */ n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Don't blow up if the. */ if (n <= 0) /* Don't blow up if the. */
n = 1; /* Window is tiny. */ n = 1; /* Window is tiny. */
} else if (n < 0) } else if (n < 0)
return forwpage(f, -n); return forwpage(f, -n);
#if CVMVAS #if CVMVAS
else /* Convert from pages. */ else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */ n *= curwp->w_ntrows; /* To lines. */
#endif #endif
/* lp = curwp->w_linep; */ /* lp = curwp->w_linep; */
lp = curwp->w_dotp ; lp = curwp->w_dotp ;
while( n && lback( lp) != curbp->b_linep) { while( n && lback( lp) != curbp->b_linep) {
lp = lback( lp) ; lp = lback( lp) ;
n -= 1 ; n -= 1 ;
} }
/* curwp->w_linep = lp; */ /* curwp->w_linep = lp; */
curwp->w_dotp = lp; curwp->w_dotp = lp;
curwp->w_doto = 0; curwp->w_doto = 0;
reposition( TRUE, (f == FALSE) ? 1 : 0) ; reposition( TRUE, (f == FALSE) ? 1 : 0) ;
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFINS; curwp->w_flag |= WFHARD | WFINS;
#else #else
curwp->w_flag |= WFHARD; curwp->w_flag |= WFHARD;
#endif #endif
return TRUE; return TRUE;
} }
/*
/* Set the mark in the current window to the value of "." in the window. * Set the mark in the current window to the value of "." in the window. No
No errors are possible. Bound to M-. set-mark. * errors are possible. Bound to "M-.".
*/ */
TBINDABLE( setmark) { boolean setmark( int f, int n) {
curwp->w_markp = curwp->w_dotp ; curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto ; curwp->w_marko = curwp->w_doto;
mloutstr( "(Mark set)") ; mloutstr( "(Mark set)") ;
return TRUE ; return TRUE ;
} }
/*
/* Swap the values of "." and "mark" in the current window. If no mark as * Swap the values of "." and "mark" in the current window. This is pretty
been previously set, set it. Bound to C-X C-X exchange-point-and-mark. * easy, because all of the hard work gets done by the standard routine
* that moves the mark about. The only possible error is "no mark". Bound to
* "C-X C-X".
*/ */
TBINDABLE( swapmark) { boolean swapmark( int f, int n) {
line_p odotp = curwp->w_dotp ; line_p odotp ;
int odoto = curwp->w_doto ; int odoto;
if( curwp->w_markp) {
curwp->w_dotp = curwp->w_markp ;
curwp->w_doto = curwp->w_marko ;
curwp->w_flag |= WFMOVE ;
}
curwp->w_markp = odotp ; if( curwp->w_markp == NULL) {
curwp->w_marko = odoto ; mloutstr( "No mark in this window") ;
return TRUE ; return FALSE ;
}
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_markp = odotp;
curwp->w_marko = odoto;
curwp->w_flag |= WFMOVE;
return TRUE;
} }
/* end of basic.c */ /* end of basic.c */

43
basic.h
View File

@ -1,32 +1,35 @@
/* basic.h -- basic commands for cursor movement in active window */ /* basic.h -- basic commands for cursor movement in active window */
#ifndef _BASIC_H_ #ifndef _BASIC_H_
# define _BASIC_H_ #define _BASIC_H_
# include "names.h" #include "retcode.h"
/* $overlap is the size of the line overlap when kbd calls page forw/back /*
if 0, page will move by 2/3 of the window size (1/3 page overlap) ** $overlap is the size of the line overlap when kbd calls page forw/back
default to 0 ** if 0, page will move by 2/3 of the window size (1/3 page overlap)
*/ ** default to 0
extern int overlap ; /* $overlap: line overlap in forw/back page */ */
#define DEFAULT_OVERLAP 0
extern int overlap ; /* line overlap in forw/back page */
/* $target (== curgoal) is the column target when doing line move */ /* $target (== curgoal) is the column target when doing line move */
extern int curgoal ; /* $target: Goal for C-P previous-line, C-N next-line */ extern int curgoal ; /* Goal for C-P previous-line, C-N next-line */
/* Bindable functions */ boolean gotobol( int f, int n) ;
BBINDABLE( backline) ; boolean gotoeol( int f, int n) ;
TBINDABLE( backpage) ; int gotoline( int f, int n) ;
BBINDABLE( forwline) ; boolean gotobob( int f, int n) ;
TBINDABLE( forwpage) ; boolean gotoeob( int f, int n) ;
TBINDABLE( gotobob) ; boolean forwline( int f, int n) ;
TBINDABLE( gotobol) ; boolean backline( int f, int n) ;
TBINDABLE( gotoeob) ; boolean forwpage( int f, int n) ;
TBINDABLE( gotoeol) ; boolean backpage( int f, int n) ;
BINDABLE( gotoline) ; boolean setmark( int f, int n) ;
TBINDABLE( setmark) ; boolean swapmark( int f, int n) ;
TBINDABLE( swapmark) ;
#endif #endif
/* end of basic.h */ /* end of basic.h */

403
bind.c
View File

@ -9,22 +9,24 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "estruct.h"
#include "bindable.h" #include "bindable.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* upmode(), ostring() */ #include "display.h"
#include "exec.h" #include "exec.h"
#include "file.h" #include "file.h"
#include "flook.h" #include "flook.h"
#include "input.h" #include "input.h"
#include "line.h" #include "line.h"
#include "mlout.h"
#include "names.h" #include "names.h"
#include "util.h" #include "util.h"
#include "window.h" #include "window.h"
static int buildlist( char *mstring) ; static int buildlist( char *mstring) ;
static char *cmdstr( unsigned c, char *seq) ; static char *cmdstr( unsigned c, char *seq) ;
static unsigned int getckey( int mflag) ; static unsigned int getckey( int mflag) ;
@ -32,175 +34,179 @@ static unsigned int stock( char *keyname) ;
static const char *getfname( unsigned keycode, const char *failmsg) ; static const char *getfname( unsigned keycode, const char *failmsg) ;
/* give me some help!!!! bring up a fake buffer and read the help file into static boolean cmdfail( const char *msg) {
it with view mode mlwrite( "%s", msg) ;
*/ return FALSE ;
}
BINDABLE( help) { BINDABLE( help) {
/* give me some help!!!!
bring up a fake buffer and read the help file into it with view mode */
char *fname = NULL; /* ptr to file returned by flook() */ char *fname = NULL; /* ptr to file returned by flook() */
/* first check if we are already here */ /* first check if we are already here */
buffer_p bp = bfind( hlpfname, FALSE, BFINVS); buffer_p bp = bfind( hlpfname, FALSE, BFINVS);
if( bp == curbp) if( bp == curbp)
return TRUE ; return TRUE ;
if( bp == NULL) { if( bp == NULL) {
fname = flook( hlpfname, FALSE) ; fname = flook( hlpfname, FALSE) ;
if( fname == NULL) if( fname == NULL)
return mloutfail( "(Help file is not online)") ; return cmdfail( "(Help file is not online)") ;
} }
/* split the current window to make room for the help stuff */ /* split the current window to make room for the help stuff */
if( wheadp->w_wndp == NULL /* One window */ if( wheadp->w_wndp == NULL /* One window */
&& splitwind( FALSE, 1) == FALSE) /* Split it */ && splitwind( FALSE, 1) == FALSE) /* Split it */
return FALSE ; return FALSE ;
if( bp == NULL) { if (bp == NULL) {
/* and read the stuff in */ /* and read the stuff in */
if( getfile( fname, FALSE) == FALSE) if (getfile(fname, FALSE) == FALSE)
return FALSE ; return FALSE;
} else } else
swbuffer( bp) ; swbuffer( bp) ;
/* make this window in VIEW mode, update all mode lines */ /* make this window in VIEW mode, update all mode lines */
curwp->w_bufp->b_mode |= MDVIEW; curwp->w_bufp->b_mode |= MDVIEW;
curwp->w_bufp->b_flag |= BFINVS; curwp->w_bufp->b_flag |= BFINVS;
upmode() ; upmode() ;
return TRUE ; return TRUE;
} }
static boolean invalidkey( void) { static boolean invalidkey( void) {
return mloutfail( "(Invalid key sequence)") ; return cmdfail( "(Invalid key sequence)") ;
} }
/* describe the command for a certain key */ /* describe the command for a certain key */
BINDABLE( deskey) { BINDABLE( deskey) {
const char cmdname[] = "describe-key" ; const char cmdname[] = "describe-key" ;
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ NSTRING] ; /* output buffer for command sequence */
/* prompt the user to type a key to describe */ /* prompt the user to type a key to describe */
mloutfmt( "%s: ", cmdname) ; mlwrite( "%s: ", cmdname) ;
/* get the command sequence to describe /* get the command sequence to describe
* change it to something we can print as well */ * change it to something we can print as well */
unsigned keycode = getckey( FALSE) ; unsigned keycode = getckey( FALSE) ;
if( keycode == (unsigned) ~0) if( keycode == (unsigned) ~0)
return invalidkey() ; return invalidkey() ;
/* output the command sequence */ /* output the command sequence */
mloutfmt( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode, mlwrite( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode,
getfname( keycode, "Not Bound")) ; getfname( keycode, "Not Bound")) ;
return TRUE ; return TRUE ;
} }
/*
/* bindtokey: * bindtokey:
* add a new key to the key binding table * add a new key to the key binding table
* *
* int f, n; command arguments [IGNORED] * int f, n; command arguments [IGNORED]
*/ */
BINDABLE( bindtokey) { BINDABLE( bindtokey) {
kbind_p ktp ; /* pointer into the command table */ kbind_p ktp ; /* pointer into the command table */
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to bind */ /* prompt the user to type in a key to bind */
mloutstr( "bind-to-key: ") ; mlwrite("bind-to-key: ");
/* get the function name to bind it to */ /* get the function name to bind it to */
nbind_p nbp = getname() ; nbind_p nbp = getname() ;
if( nbp == NULL) /* abort */ if( nbp == NULL) /* abort */
return FALSE ; return FALSE ;
fnp_t kfunc = nbp->n_func ; fnp_t kfunc = nbp->n_func ;
if( kfunc == NULL) if( kfunc == NULL)
return mloutfail( "(No such function)") ; return cmdfail( "(No such function)") ;
mloutfmt( "bind-to-key %s: ", bind_name( nbp)) ; mlwrite( "bind-to-key %s: ", bind_name( nbp)) ;
/* get the command sequence to bind */ /* get the command sequence to bind */
boolean prefix_f = (kfunc == (fnp_t) metafn) || (kfunc == (fnp_t) cex) || boolean prefix_f = (kfunc == metafn) || (kfunc == cex) ||
(kfunc == (fnp_t) unarg) || (kfunc == (fnp_t) ctrlg) ; (kfunc == unarg) || (kfunc == ctrlg) ;
int c = getckey( prefix_f) ; int c = getckey( prefix_f) ;
if( c == ~0) if( c == ~0)
return invalidkey() ; return invalidkey() ;
/* change it to something we can print as well */ /* change it to something we can print as well */
/* and dump it out */ /* and dump it out */
ostring( cmdstr( c, outseq)) ; ostring( cmdstr( c, outseq)) ;
/* key sequence can't be an active prefix key */ /* key sequence can't be an active prefix key */
if( c == metac || c == ctlxc || c == reptc || c == abortc) { if( c == metac || c == ctlxc || c == reptc || c == abortc) {
if( (c == metac && kfunc == (fnp_t) metafn) if( (c == metac && kfunc == metafn)
|| (c == ctlxc && kfunc == (fnp_t) cex) || (c == ctlxc && kfunc == cex)
|| (c == reptc && kfunc == (fnp_t) unarg) || (c == reptc && kfunc == unarg)
|| (c == abortc && kfunc == (fnp_t) ctrlg)) || (c == abortc && kfunc == ctrlg))
return TRUE ; /* be silent if keep current */ return TRUE ;
return mloutfail( "(Can't bind to active prefix)") ; return cmdfail( "(Can't bind to active prefix)") ;
} }
/* if the function is a prefix key */ /* if the function is a prefix key */
if( prefix_f) { if( prefix_f) {
/* remove existing binding for the prefix */ /* remove existing binding for the prefix */
for( ktp = keytab ; ktp->k_code != 0 ; ktp++) for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if( ktp->k_nbp == nbp) { if( ktp->k_nbp == nbp) {
delkeybinding( ktp->k_code) ; delkeybinding( ktp->k_code) ;
break ; break ;
} }
/* set the appropriate global prefix variable */ /* set the appropriate global prefix variable */
if( kfunc == (fnp_t) metafn) if( kfunc == metafn)
metac = c ; metac = c ;
else if( kfunc == (fnp_t) cex) else if( kfunc == cex)
ctlxc = c ; ctlxc = c ;
if( kfunc == (fnp_t) unarg) if( kfunc == unarg)
reptc = c ; reptc = c ;
if( kfunc == (fnp_t) ctrlg) if( kfunc == ctrlg)
abortc = c ; abortc = c ;
} }
ktp = setkeybinding( c, nbp) ; ktp = setkeybinding( c, nbp) ;
if( ktp->k_code == 0) if( ktp->k_code == 0)
return mloutfail( "Binding table FULL!") ; return cmdfail( "Binding table FULL!") ;
return TRUE ; return TRUE ;
} }
/*
/* unbindkey: * unbindkey:
* delete a key from the key binding table * delete a key from the key binding table
* *
* int f, n; command arguments [IGNORED] * int f, n; command arguments [IGNORED]
*/ */
BINDABLE( unbindkey) { BINDABLE( unbindkey) {
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to unbind */ /* prompt the user to type in a key to unbind */
mloutstr( "unbind-key: ") ; mlwrite( "unbind-key: ") ;
/* get the command sequence to unbind */ /* get the command sequence to unbind */
int c = getckey( FALSE) ; /* get a command sequence */ int c = getckey( FALSE) ; /* get a command sequence */
if( c == ~0) if( c == ~0)
return invalidkey() ; return invalidkey() ;
/* change it to something we can print as well */ /* change it to something we can print as well */
/* and dump it out */ /* and dump it out */
ostring( cmdstr( c, outseq)) ; ostring( cmdstr( c, outseq)) ;
/* prefix key sequence can't be undound, just redefined */ /* prefix key sequence can't be undound, just redefined */
if( c == reptc || c == abortc) if( c == reptc || c == abortc)
return mloutfail( "(Can't unbind prefix)") ; return cmdfail( "(Can't unbind prefix)") ;
/* if it isn't bound, bitch */ /* if it isn't bound, bitch */
if( delkeybinding( c) == FALSE) if( delkeybinding( c) == FALSE) {
return mloutfail( "(Key not bound)") ; mlwrite( "(Key not bound)") ;
return FALSE ;
}
return TRUE ; return TRUE ;
} }
/*
/* does source include sub? * does source include sub?
* *
* char *source; string to search in * char *source; string to search in
* char *sub; substring to look for * char *sub; substring to look for
@ -208,8 +214,8 @@ BINDABLE( unbindkey) {
static boolean strinc( const char *source, const char *sub) { static boolean strinc( const char *source, const char *sub) {
/* for each character in the source string */ /* for each character in the source string */
for( ; *source ; source++) { for( ; *source ; source++) {
const char *nxtsp ; /* next ptr into source */ const char *nxtsp ; /* next ptr into source */
const char *tp ; /* ptr into substring */ const char *tp ; /* ptr into substring */
nxtsp = source; nxtsp = source;
@ -226,7 +232,6 @@ static boolean strinc( const char *source, const char *sub) {
return FALSE ; return FALSE ;
} }
/* describe bindings /* describe bindings
* bring up a fake buffer and list the key bindings * bring up a fake buffer and list the key bindings
* into it with view mode * into it with view mode
@ -235,166 +240,168 @@ BINDABLE( desbind) {
return buildlist( "") ; return buildlist( "") ;
} }
/* Apropos (List functions that match a substring) */ /* Apropos (List functions that match a substring) */
BINDABLE( apro) { BINDABLE( apro) {
char *mstring ; /* string to match cmd names to */ char *mstring ; /* string to match cmd names to */
int status = newmlarg( &mstring, "apropos: ", 0) ; int status = newmlarg( &mstring, "apropos: ", 0) ;
if( status == TRUE) { if( status == TRUE) {
status = buildlist( mstring) ; status = buildlist( mstring) ;
free( mstring) ; free( mstring) ;
} else if( status == FALSE) } else if( status == FALSE)
status = buildlist( "") ; /* build list of all commands */ status = buildlist( "") ; /* build list of all commands */
return status ; return status ;
} }
/*
/* build a binding list (limited or full) * build a binding list (limited or full)
* *
* char *mstring; match string if a partial list, "" matches all * char *mstring; match string if a partial list, "" matches all
*/ */
static int buildlist( char *mstring) { static int buildlist( char *mstring) {
#define PADDING 28 struct window *wp; /* scanning pointer to windows */
char outseq[ PADDING + 8] ; /* output buffer for command + keystroke */ kbind_p ktp; /* pointer into the command table */
nbind_p nptr;/* pointer into the name binding table */
struct buffer *bp; /* buffer to put binding list into */
char outseq[80]; /* output buffer for keystroke sequence */
/* split the current window to make room for the binding list */ /* split the current window to make room for the binding list */
if( wheadp->w_wndp == NULL /* One window */ if( wheadp->w_wndp == NULL /* One window */
&& splitwind( FALSE, 1) == FALSE) /* Split it */ && splitwind( FALSE, 1) == FALSE) /* Split it */
return FALSE ; return FALSE;
/* and get a buffer for it */ /* and get a buffer for it */
buffer_p bp = bfind( "*Binding list*", TRUE, 0) ; bp = bfind("*Binding list*", TRUE, 0);
if( bp == NULL || bclear( bp) == FALSE) if( bp == NULL || bclear( bp) == FALSE)
return mloutfail( "Can't display binding list") ; return cmdfail( "Can't display binding list") ;
/* let us know this is in progress */ /* let us know this is in progress */
mloutstr( "(Building binding list)") ; mlwrite("(Building binding list)");
/* disconnect the current buffer */ /* disconnect the current buffer */
if( --curbp->b_nwnd == 0) { /* Last use. */ if (--curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp ; curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto ; curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp ; curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko ; curbp->b_marko = curwp->w_marko;
} }
/* connect the current window to this buffer */ /* connect the current window to this buffer */
curbp = bp ; /* make this buffer current in current window */ curbp = bp; /* make this buffer current in current window */
bp->b_mode = 0 ; /* no modes active in binding list */ bp->b_mode = 0; /* no modes active in binding list */
bp->b_nwnd++ ; /* mark us as more in use */ bp->b_nwnd++; /* mark us as more in use */
window_p wp = curwp ; wp = curwp;
wp->w_bufp = bp ; wp->w_bufp = bp;
wp->w_linep = bp->b_linep ; wp->w_linep = bp->b_linep;
wp->w_flag = WFHARD | WFFORCE ; wp->w_flag = WFHARD | WFFORCE;
wp->w_dotp = bp->b_dotp ; wp->w_dotp = bp->b_dotp;
wp->w_doto = bp->b_doto ; wp->w_doto = bp->b_doto;
wp->w_markp = NULL ; wp->w_markp = NULL;
wp->w_marko = 0 ; wp->w_marko = 0;
/* build the contents of this window, inserting it line by line */ /* build the contents of this window, inserting it line by line */
for( nbind_p nptr = names ; nptr->n_func != NULL ; nptr++) { for( nptr = names ; nptr->n_func != NULL ; nptr++) {
int cpos ; /* current position to use in outseq */ int cpos ; /* current position to use in outseq */
/* if we are executing an apropos command..... */ /* if we are executing an apropos command..... */
/* and current string doesn't include the search string */ /* and current string doesn't include the search string */
if( *mstring && strinc( bind_name( nptr), mstring) == FALSE) if( *mstring && strinc( bind_name( nptr), mstring) == FALSE)
continue ; continue ;
/* add in the command name */ /* add in the command name */
mystrscpy( outseq, bind_name( nptr), sizeof outseq) ; mystrscpy( outseq, bind_name( nptr), sizeof outseq) ;
cpos = strlen( outseq) ; cpos = strlen(outseq);
/* search down any keys bound to this */ /* search down any keys bound to this */
for( kbind_p ktp = keytab ; ktp->k_code != 0 ; ktp++) { for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if( ktp->k_nbp == nptr) { if( ktp->k_nbp == nptr) {
/* padd out some spaces */ /* padd out some spaces */
while( cpos < PADDING) while (cpos < 28)
outseq[ cpos++] = ' ' ; outseq[cpos++] = ' ';
/* add in the command sequence */ /* add in the command sequence */
cmdstr( ktp->k_code, &outseq[ cpos]) ; cmdstr(ktp->k_code, &outseq[cpos]);
strcat( outseq, "\n") ; strcat(outseq, "\n");
/* and add it as a line into the buffer */ /* and add it as a line into the buffer */
if( linstr( outseq) != TRUE) if (linstr(outseq) != TRUE)
return FALSE ; return FALSE;
cpos = 0 ; /* and clear the line */ cpos = 0; /* and clear the line */
} }
} }
/* if no key was bound, we need to dump it anyway */ /* if no key was bound, we need to dump it anyway */
if( cpos > 0) { if (cpos > 0) {
outseq[ cpos++] = '\n'; outseq[cpos++] = '\n';
outseq[ cpos] = 0; outseq[cpos] = 0;
if( linstr( outseq) != TRUE) if (linstr(outseq) != TRUE)
return FALSE ; return FALSE;
} }
} }
bp->b_mode |= MDVIEW ; /* put this buffer view mode */ bp->b_mode |= MDVIEW; /* put this buffer view mode */
bp->b_flag &= ~BFCHG ; /* don't flag this as a change */ bp->b_flag &= ~BFCHG; /* don't flag this as a change */
wp->w_dotp = lforw( bp->b_linep) ; /* back to the beginning */ wp->w_dotp = lforw(bp->b_linep); /* back to the beginning */
wp->w_doto = 0 ; wp->w_doto = 0;
upmode() ; /* and update ALL mode lines */ upmode() ; /* and update ALL mode lines */
mloutstr( "") ; /* clear the mode line */ mlwrite(""); /* clear the mode line */
return TRUE ; return TRUE;
} }
/*
/* get a command key sequence from the keyboard * get a command key sequence from the keyboard
* *
* int mflag; going for a meta sequence? * int mflag; going for a meta sequence?
* returns ~0 on failure * returns ~0 on failure
*/ */
static unsigned int getckey( int mflag) { static unsigned int getckey( int mflag) {
unsigned int c ; /* character fetched */ unsigned int c ; /* character fetched */
/* check to see if we are executing a command line */ /* check to see if we are executing a command line */
if( clexec) { if( clexec) {
char *tok = getnewtokval() ; /* get the next token */ char *tok = getnewtokval() ; /* get the next token */
if( tok == NULL) if( tok == NULL)
c = ~0 ; /* return invalid key on failure */ c = ~0 ; /* return invalid key on failure */
else { else {
c = stock( tok) ; c = stock( tok) ;
free( tok) ; free( tok) ;
} }
} else { /* or the normal way */ } else { /* or the normal way */
if( mflag) if( mflag)
c = get1key() ; c = get1key() ;
else else
c = getcmd() ; c = getcmd() ;
} }
return c ; return c ;
} }
/*
/* execute the startup file * execute the startup file
* *
* char *fname; name of startup file (null if default) * char *fname; name of startup file (null if default)
*/ */
int startup( const char *fname) { int startup( const char *fname) {
if( !fname || *fname == 0) /* use default if empty parameter */ if( !fname || *fname == 0) /* use default if empty parameter */
fname = rcfname ; fname = rcfname ;
fname = flook( fname, TRUE) ; /* look up the startup file */ fname = flook( fname, TRUE) ; /* look up the startup file */
if( fname == NULL) /* if it isn't around, don't sweat it */ if( fname == NULL) /* if it isn't around, don't sweat it */
return TRUE ; return TRUE ;
return dofile( fname) ; /* otherwise, execute the sucker */ return dofile( fname) ; /* otherwise, execute the sucker */
} }
/*
/* change a key command to a string we can print out * change a key command to a string we can print out
* *
* int c; sequence to translate * int c; sequence to translate
* char *seq; destination string for sequence * char *seq; destination string for sequence
*/ */
static char *cmdstr( unsigned c, char *seq) { static char *cmdstr( unsigned c, char *seq) {
char *ptr = seq ; /* pointer into current position in sequence */ char *ptr = seq ; /* pointer into current position in sequence */
/* apply meta sequence if needed */ /* apply meta sequence if needed */
if( c & META) { if( c & META) {
@ -404,14 +411,14 @@ static char *cmdstr( unsigned c, char *seq) {
/* apply ^X sequence if needed */ /* apply ^X sequence if needed */
if( c & CTLX) { if( c & CTLX) {
if( ctlxc & CTL_) if( ctlxc & CTRL)
*ptr++ = '^' ; *ptr++ = '^' ;
*ptr++ = ctlxc & ~PRFXMASK ; *ptr++ = ctlxc & ~PRFXMASK ;
} }
/* apply control sequence if needed */ /* apply control sequence if needed */
if( c & CTL_) if( c & CTRL)
*ptr++ = '^' ; *ptr++ = '^' ;
/* apply SPEC sequence if needed */ /* apply SPEC sequence if needed */
@ -421,24 +428,22 @@ static char *cmdstr( unsigned c, char *seq) {
} }
/* and output the final sequence */ /* and output the final sequence */
ptr += unicode_to_utf8( c & ~PRFXMASK, ptr) ; ptr += unicode_to_utf8( c & ~PRFXMASK, ptr) ;
*ptr = 0 ; /* terminate the string */ *ptr = 0 ; /* terminate the string */
return seq ; return seq ;
} }
static const char *getfname( unsigned keycode, const char *failmsg) { static const char *getfname( unsigned keycode, const char *failmsg) {
/* takes a key code and gets the name of the function bound to it */ /* takes a key code and gets the name of the function bound to it */
kbind_p kbp = getkeybinding( keycode) ; kbind_p kbp = getkeybinding( keycode) ;
if( kbp->k_code == 0) if( kbp->k_code == 0)
return failmsg ; return failmsg ;
const char *found = bind_name( kbp->k_nbp) ; const char *found = bind_name( kbp->k_nbp) ;
assert( *found) ; assert( *found) ;
return found ; return found ;
} }
/* stock: /* stock:
* String key name TO Command Key * String key name TO Command Key
* *
@ -461,7 +466,7 @@ static unsigned int stock( char *keyname) {
/* a control char? */ /* a control char? */
if( *keyname == '^' && keyname[ 1] != 0) { if( *keyname == '^' && keyname[ 1] != 0) {
c |= CTL_ ; c |= CTRL ;
++keyname ; ++keyname ;
} }
@ -472,16 +477,16 @@ static unsigned int stock( char *keyname) {
} }
/* only one character left to parse */ /* only one character left to parse */
if( !*keyname || keyname[1]) if( !*keyname || keyname[1])
return ~0 ; return ~0 ;
/* only way to redefine ^X is by quoting binary value */ /* only way to redefine ^X is by quoting binary value */
if( *keyname < 32 || *keyname == 0x7F) { if( *keyname < 32 || *keyname == 0x7F) {
c |= CTL_ ; c |= CTRL ;
*keyname ^= 0x40 ; *keyname ^= 0x40 ;
} else if( c && !(c & SPEC) } else if( c && !(c & SPEC)
&& *keyname >= 'a' && *keyname <= 'z') && *keyname >= 'a' && *keyname <= 'z')
/* make sure we are not lower case (not with function keys) */ /* make sure we are not lower case (not with function keys) */
*keyname -= 32 ; *keyname -= 32 ;
/* the final sequence... */ /* the final sequence... */
@ -489,19 +494,19 @@ static unsigned int stock( char *keyname) {
return c ; return c ;
} }
/*
/* string key name to binding name.... * string key name to binding name....
* *
* char *skey; name of key to get binding for * char *skey; name of key to get binding for
*/ */
const char *transbind( char *skey) { const char *transbind( char *skey) {
static const char failmsg[] = "ERROR" ; static const char failmsg[] = "ERROR" ;
unsigned c = stock( skey) ; unsigned c = stock( skey) ;
if( c == (unsigned) ~0) if( c == (unsigned) ~0)
return failmsg ; return failmsg ;
else else
return getfname( c, failmsg) ; return getfname( c, failmsg) ;
} }
/* end of bind.c */ /* end of bind.c */

6
bind.h
View File

@ -1,5 +1,3 @@
/* bind.h -- bindable functions dealing with name and key bindings */
#ifndef _BIND_H_ #ifndef _BIND_H_
#define _BIND_H_ #define _BIND_H_
@ -16,8 +14,6 @@ BINDABLE( unbindkey) ;
int startup( const char *fname) ; int startup( const char *fname) ;
/* find a key to function association in the key to function mapping table */ /* find a key to function association in the key to function mapping table */
const char *transbind( char *skey) ; /* by string representation of key */ const char *transbind( char *skey) ; /* by string representation of key */
#endif #endif
/* end of bind.h */

View File

@ -3,127 +3,146 @@
#include <stdlib.h> #include <stdlib.h>
#include "defines.h" #include "defines.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* vttidy() */ #include "display.h"
#include "estruct.h"
#include "file.h" #include "file.h"
#include "input.h" #include "input.h"
#include "lock.h" #include "lock.h"
#include "mlout.h" #include "mlout.h"
#include "terminal.h" #include "terminal.h"
/*
/* Fancy quit command, as implemented by Norm. If any buffer has changed * Fancy quit command, as implemented by Norm. If the any buffer has
do a write on that buffer and exit emacs, otherwise simply exit. * changed do a write on that buffer and exit emacs, otherwise simply exit.
*/ */
BINDABLE( quickexit) { int quickexit(int f, int n)
buffer_p oldcb = curbp ; /* save in case we fail */ {
for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { struct buffer *bp; /* scanning pointer to buffers */
if( (bp->b_flag & (BFCHG | BFTRUNC | BFINVS)) == BFCHG) { struct buffer *oldcb; /* original current buffer */
/* Changed, Not truncated and real buffer */ int status;
curbp = bp ; /* make that buffer cur */
mloutfmt( "(Saving %s)", bp->b_fname) ;
int status = filesave( f, n) ;
if( status != TRUE) {
curbp = oldcb ; /* restore curbp */
return status ;
}
}
}
return quit( f, n) ; /* conditionally quit */ oldcb = curbp; /* save in case we fail */
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag & BFCHG) != 0 /* Changed. */
&& (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */
&& (bp->b_flag & BFINVS) == 0) { /* Real. */
curbp = bp; /* make that buffer cur */
mloutfmt( "(Saving %s)", bp->b_fname) ;
#if PKCODE
#else
mloutstr( "\n") ;
#endif
if ((status = filesave(f, n)) != TRUE) {
curbp = oldcb; /* restore curbp */
return status;
}
}
bp = bp->b_bufp; /* on to the next buffer */
}
quit(f, n); /* conditionally quit */
return TRUE;
} }
/*
/* Quit command. If an argument, always quit. Otherwise confirm if a buffer * Quit command. If an argument, always quit. Otherwise confirm if a buffer
* has been changed and not written out. Normally bound to "C-X C-C". * has been changed and not written out. Normally bound to "C-X C-C".
*/ */
BINDABLE( quit) { int quit(int f, int n)
int s ; /* status of user query */ {
int s;
if( f != FALSE /* Argument forces it. */ if (f != FALSE /* Argument forces it. */
|| anycb() == FALSE /* All buffers clean. */ || anycb() == FALSE /* All buffers clean. */
/* User says it's OK. */ /* User says it's OK. */
|| (s = mlyesno( "Modified buffers exist. Leave anyway")) == TRUE) { || (s =
#if (FILOCK && BSD) || SVR4 mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
if( lockrel() != TRUE) { #if (FILOCK && BSD) || SVR4
TTputc('\n') ; if (lockrel() != TRUE) {
TTputc('\r') ; TTputc('\n');
TTclose() ; TTputc('\r');
TTkclose() ; TTclose();
exit( EXIT_FAILURE) ; TTkclose();
} exit( EXIT_FAILURE) ;
}
#endif #endif
vttidy() ; vttidy();
if( f) if (f)
exit( n) ; exit(n);
else else
exit( EXIT_SUCCESS) ; exit( EXIT_SUCCESS) ;
} }
mloutstr( "") ;
mloutstr( "") ; return s;
return s ;
} }
/*
/* Begin a keyboard macro. * Begin a keyboard macro.
* Error if not at the top level in keyboard processing. Set up variables and * Error if not at the top level in keyboard processing. Set up variables and
* return. * return.
*/ */
BBINDABLE( ctlxlp) { int ctlxlp(int f, int n)
if( kbdmode != STOP) {
return mloutfail( "%Macro already active") ; if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
mloutstr( "(Start macro)") ; return FALSE;
kbdptr = kbdm ; }
kbdend = kbdptr ; mloutstr( "(Start macro)") ;
kbdmode = RECORD ; kbdptr = &kbdm[0];
return TRUE ; kbdend = kbdptr;
kbdmode = RECORD;
return TRUE;
} }
/*
/* End keyboard macro. Check for the same limit conditions as the above * End keyboard macro. Check for the same limit conditions as the above
* routine. Set up the variables and return to the caller. * routine. Set up the variables and return to the caller.
*/ */
BBINDABLE( ctlxrp) { int ctlxrp(int f, int n)
if( kbdmode == STOP) {
return mloutfail( "%Macro not active") ; if (kbdmode == STOP) {
mloutstr( "%Macro not active") ;
if (kbdmode == RECORD) { return FALSE;
mloutstr( "(End macro)") ; }
kbdmode = STOP; if (kbdmode == RECORD) {
} mloutstr( "(End macro)") ;
kbdmode = STOP;
return TRUE ; }
return TRUE;
} }
/*
/* Execute a macro. * Execute a macro.
* The command argument is the number of times to loop. Quit as soon as a * The command argument is the number of times to loop. Quit as soon as a
* command gets an error. Return TRUE if all ok, else FALSE. * command gets an error. Return TRUE if all ok, else FALSE.
*/ */
BBINDABLE( ctlxe) { int ctlxe(int f, int n)
if( kbdmode != STOP) {
return mloutfail( "%Macro already active") ; if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
if( n <= 0) return FALSE;
return TRUE ; }
if (n <= 0)
kbdrep = n ; /* remember how many times to execute */ return TRUE;
kbdmode = PLAY ; /* start us in play mode */ kbdrep = n; /* remember how many times to execute */
kbdptr = kbdm ; /* at the beginning */ kbdmode = PLAY; /* start us in play mode */
return TRUE ; kbdptr = &kbdm[0]; /* at the beginning */
return TRUE;
} }
/*
/* abort: * abort:
* Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
* Sometimes called as a routine, to do general aborting of stuff. * Sometimes called as a routine, to do general aborting of stuff.
*/ */
BINDABLE( ctrlg) { int ctrlg( int f, int n) {
kbdmode = STOP ; kbdmode = STOP ;
mloutfmt( "%B(Aborted)") ; mloutfmt( "%B(Aborted)") ;
return ABORT ; return ABORT ;
} }
/* end of bindable.c */ /* end of bindable.c */

View File

@ -1,16 +1,9 @@
/* bindable.h -- misc bindable functions */
#ifndef _BINDABLE_H_
#define _BINDABLE_H_
#include "names.h" #include "names.h"
/* functions that can be bound to keys or procedure names */ /* functions that can be bound to keys or procedure names */
BBINDABLE( ctlxe) ; BINDABLE( quickexit) ;
BBINDABLE( ctlxlp) ; BINDABLE( quit) ;
BBINDABLE( ctlxrp) ; BINDABLE( ctlxlp) ;
BINDABLE( ctrlg) ; /* ABORT */ BINDABLE( ctlxrp) ;
BINDABLE( quickexit) ; BINDABLE( ctlxe) ;
BINDABLE( quit) ; BINDABLE( ctrlg) ;
#endif
/* end of bindable.h */

903
buffer.c

File diff suppressed because it is too large Load Diff

120
buffer.h
View File

@ -1,82 +1,74 @@
/* buffer.h -- buffer type and functions */
#ifndef _BUFFER_H_ #ifndef _BUFFER_H_
# define _BUFFER_H_ #define _BUFFER_H_
#include "line.h" #include "line.h"
#include "names.h"
/* Text is kept in buffers. A buffer header, described below, exists for typedef char fname_t[ 256] ; /* file name type */
every buffer in the system. The buffers are kept in a big list, so that typedef char bname_t[ 16] ; /* buffer name type */
commands that search for a buffer by name can find the buffer header.
There is a safe store for the dot and mark in the header, but this is
only valid if the buffer is not being displayed (that is, if "b_nwnd" is
0). The text for the buffer is kept in a circularly linked list of
lines, with a pointer to the header line in "b_linep".
Buffers may be "Inactive" which means the files associated with them /*
have not been read in yet. These get read in at "use buffer" time. * Text is kept in buffers. A buffer header, described below, exists for every
* buffer in the system. The buffers are kept in a big list, so that commands
* that search for a buffer by name can find the buffer header. There is a
* safe store for the dot and mark in the header, but this is only valid if
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
* the buffer is kept in a circularly linked list of lines, with a pointer to
* the header line in "b_linep".
* Buffers may be "Inactive" which means the files associated with them
* have not been read in yet. These get read in at "use buffer" time.
*/ */
typedef char fname_t[ 256] ; /* file name type */
typedef char bname_t[ 16] ; /* buffer name type */
typedef struct buffer { typedef struct buffer {
struct buffer *b_bufp ; /* Link to next struct buffer */ struct buffer *b_bufp; /* Link to next struct buffer */
line_p b_dotp ; /* Link to "." struct line structure */ line_p b_dotp ; /* Link to "." struct line structure */
line_p b_markp ; /* The same as the above two, */ line_p b_markp ; /* The same as the above two, */
line_p b_linep ; /* Link to the header struct line */ line_p b_linep ; /* Link to the header struct line */
int b_doto ; /* Offset of "." in above struct line */ int b_doto; /* Offset of "." in above struct line */
int b_marko ; /* but for the "mark" */ int b_marko; /* but for the "mark" */
int b_mode ; /* editor mode of this buffer */ int b_mode; /* editor mode of this buffer */
char b_active ; /* window activated flag */ char b_active; /* window activated flag */
char b_nwnd ; /* Count of windows on buffer */ char b_nwnd; /* Count of windows on buffer */
char b_flag ; /* Flags */ char b_flag; /* Flags */
fname_t b_fname ; /* File name */ fname_t b_fname ; /* File name */
bname_t b_bname ; /* Buffer name */ bname_t b_bname ; /* Buffer name */
} *buffer_p ; } *buffer_p ;
extern buffer_p curbp ; /* Current buffer */ extern buffer_p curbp ; /* Current buffer */
extern buffer_p bheadp ; /* Head of list of buffers */ extern buffer_p bheadp ; /* Head of list of buffers */
extern buffer_p blistp ; /* Buffer for C-X C-B */ extern buffer_p blistp ; /* Buffer for C-X C-B */
#define BFINVS 0x01 /* Internal invisable buffer */ #define BFINVS 0x01 /* Internal invisable buffer */
#define BFCHG 0x02 /* Changed since last write */ #define BFCHG 0x02 /* Changed since last write */
#define BFTRUNC 0x04 /* buffer was truncated when read */ #define BFTRUNC 0x04 /* buffer was truncated when read */
/* mode flags */ /* mode flags */
#define NUMMODES 9 /* # of defined modes */ #define NUMMODES 9 /* # of defined modes */
#define MDWRAP 0x0001 /* word wrap */ #define MDWRAP 0x0001 /* word wrap */
#define MDCMOD 0x0002 /* C indentation and fence match */ #define MDCMOD 0x0002 /* C indentation and fence match */
#define MDEXACT 0x0004 /* Exact matching for searches */ #define MDEXACT 0x0004 /* Exact matching for searches */
#define MDVIEW 0x0008 /* read-only buffer */ #define MDVIEW 0x0008 /* read-only buffer */
#define MDOVER 0x0010 /* overwrite mode */ #define MDOVER 0x0010 /* overwrite mode */
#define MDMAGIC 0x0020 /* regular expresions in search */ #define MDMAGIC 0x0020 /* regular expresions in search */
#define MDASAVE 0x0040 /* auto-save mode */ #define MDASAVE 0x0040 /* auto-save mode */
#define MDUTF8 0x0080 /* utf8 mode */ #define MDUTF8 0x0080 /* utf8 mode */
#define MDDOS 0x0100 /* CRLF eol mode */ #define MDDOS 0x0100 /* CRLF eol mode */
extern const char *modename[ NUMMODES] ; /* text names of modes */
extern int gmode ; /* global editor mode */
/* Bindable functions */ extern const char *modename[] ; /* text names of modes */
BINDABLE( killbuffer) ; extern int gmode ; /* global editor mode */
BINDABLE( listbuffers) ;
BINDABLE( namebuffer) ;
BINDABLE( nextbuffer) ;
BINDABLE( unmark) ;
BINDABLE( usebuffer) ;
boolean anycb( void) ; /* Any changed buffer? */
int bclear( buffer_p bp) ; /* empty buffer */
int swbuffer( buffer_p bp) ; /* switch to buffer, make it current */
int zotbuf( buffer_p bp) ; /* remove buffer */
/* Lookup a buffer by name. If not found and create_f is TRUE then create int usebuffer( int f, int n) ;
it with flags set. int nextbuffer( int f, int n) ;
*/ int swbuffer( buffer_p bp) ;
buffer_p bfind( const char *bname, boolean create_f, int flags) ; int killbuffer( int f, int n) ;
int zotbuf( buffer_p bp) ;
int namebuffer( int f, int n) ;
int listbuffers( int f, int n) ;
int anycb( void) ;
int bclear( buffer_p bp) ;
int unmark( int f, int n) ;
/* Lookup a buffer by name. */
buffer_p bfind( const char *bname, int cflag, int bflag) ;
#endif #endif
/* end of buffer.h */

View File

@ -1,14 +1,17 @@
/* display.c -- implements display.h */ /* display.c -- implements display.h */
#include "display.h" #include "display.h"
#define REVSTA 1 /* Status line appears in reverse video */ #define REVSTA 1 /* Status line appears in reverse video */
/* The functions in this file handle redisplay. There are two halves, the /* display.c
ones that update the virtual display screen, and the ones that make the *
physical display screen the same as the virtual display screen. These * The functions in this file handle redisplay. There are two halves, the
functions use hints that are left in the windows by the commands. * ones that update the virtual display screen, and the ones that make the
* physical display screen the same as the virtual display screen. These
Modified by Petri Kutvonen * functions use hints that are left in the windows by the commands.
*
* Modified by Petri Kutvonen
*/ */
#include <errno.h> #include <errno.h>
@ -248,37 +251,40 @@ static void vteeol( void) {
vcp[ vtcol++] = ' ' ; vcp[ vtcol++] = ' ' ;
} }
/* upscreen: /*
* upscreen:
* user routine to force a screen update * user routine to force a screen update
* always finishes complete update * always finishes complete update
*/ */
BINDABLE( upscreen) { int upscreen(int f, int n)
update( TRUE) ; {
return TRUE ; update(TRUE);
return TRUE;
} }
#if SCROLLCODE #if SCROLLCODE
static int scrflags; static int scrflags;
#endif #endif
/*
/* Make sure that the display is right. This is a three part process. * Make sure that the display is right. This is a three part process. First,
First, scan through all of the windows looking for dirty ones. Check * scan through all of the windows looking for dirty ones. Check the framing,
the framing, and refresh the screen. Second, make sure that "currow" * and refresh the screen. Second, make sure that "currow" and "curcol" are
and "curcol" are correct for the current window. Third, make the * correct for the current window. Third, make the virtual and physical
virtual and physical screens the same. * screens the same.
*
boolean force_f ; force update past type ahead? * int force; force update past type ahead?
*/ */
int update( boolean force_f) { int update(int force)
{
struct window *wp; struct window *wp;
#if TYPEAH && ! PKCODE #if TYPEAH && ! PKCODE
if( force_f == FALSE && typahead()) if (force == FALSE && typahead())
return TRUE; return TRUE;
#endif #endif
#if VISMAC == 0 #if VISMAC == 0
if( force_f == FALSE && kbdmode == PLAY) if (force == FALSE && kbdmode == PLAY)
return TRUE; return TRUE;
#endif #endif
@ -353,7 +359,7 @@ int update( boolean force_f) {
updgar(); updgar();
/* update the virtual screen to the physical screen */ /* update the virtual screen to the physical screen */
updupd( force_f) ; updupd(force);
/* update the cursor and flush the buffers */ /* update the cursor and flush the buffers */
movecursor(currow, curcol - lbound); movecursor(currow, curcol - lbound);

View File

@ -1,12 +1,10 @@
/* display.h -- display functionality */
#ifndef _DISPLAY_H_ #ifndef _DISPLAY_H_
# define _DISPLAY_H_ #define _DISPLAY_H_
# include <stdarg.h> #include <stdarg.h>
# include "estruct.h" #include "estruct.h"
# include "names.h" /* BINDABLE() */ #include "utf8.h"
# include "utf8.h" /* unicode_t */
extern int mpresf ; /* Stuff in message line */ extern int mpresf ; /* Stuff in message line */
extern int scrollcount ; /* number of lines to scroll */ extern int scrollcount ; /* number of lines to scroll */
@ -15,13 +13,11 @@ extern int disinp ; /* display input characters (echo) */
extern int gfcolor ; /* global forgrnd color (white) */ extern int gfcolor ; /* global forgrnd color (white) */
extern int gbcolor ; /* global backgrnd color (black) */ extern int gbcolor ; /* global backgrnd color (black) */
/* Bindable functions */
BINDABLE( upscreen) ;
void vtinit( void) ; void vtinit( void) ;
void vtfree( void) ; void vtfree( void) ;
void vttidy( void) ; void vttidy( void) ;
int update( boolean force_f) ; int upscreen( int f, int n) ;
int update( int force) ;
void updpos( void) ; void updpos( void) ;
void upddex( void) ; void upddex( void) ;
void updgar( void) ; void updgar( void) ;
@ -37,13 +33,13 @@ void echos( const char *s) ;
void rubout( void) ; void rubout( void) ;
void getscreensize( int *widthp, int *heightp) ; void getscreensize( int *widthp, int *heightp) ;
# if UNIX #if UNIX
# include <signal.h> #include <signal.h>
# ifdef SIGWINCH #ifdef SIGWINCH
extern int chg_width, chg_height ; extern int chg_width, chg_height ;
void sizesignal( int signr) ; void sizesignal( int signr) ;
# endif
# endif
#endif #endif
/* end of display.h */ #endif
#endif

34
eval.c
View File

@ -1,7 +1,9 @@
/* eval.c -- implements eval.h */ /* eval.c -- implements eval.h */
#include "eval.h" #include "eval.h"
/* Expression evaluation functions /* eval.c
*
* Expression evaluation functions
* *
* written 1986 by Daniel Lawrence * written 1986 by Daniel Lawrence
* modified by Petri Kutvonen * modified by Petri Kutvonen
@ -208,7 +210,7 @@ static struct {
{ "and", UFAND | DYNAMIC }, /* logical and */ { "and", UFAND | DYNAMIC }, /* logical and */
{ "asc", UFASCII | MONAMIC }, /* char to integer conversion */ { "asc", UFASCII | MONAMIC }, /* char to integer conversion */
{ "ban", UFBAND | DYNAMIC }, /* bitwise and 9-10-87 jwm */ { "ban", UFBAND | DYNAMIC }, /* bitwise and 9-10-87 jwm */
{ "bin", UFBIND | MONAMIC }, /* look up function name bound to key */ { "bin", UFBIND | MONAMIC }, /* loopup what function name is bound to a key */
{ "bno", UFBNOT | MONAMIC }, /* bitwise not */ { "bno", UFBNOT | MONAMIC }, /* bitwise not */
{ "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */ { "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */
{ "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */ { "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */
@ -795,13 +797,14 @@ static char *gtenv( char *vname) {
return errorm ; return errorm ;
} }
/*
/* set a variable * set a variable
* *
* int f; default flag * int f; default flag
* int n; numeric arg (can overide prompted value) * int n; numeric arg (can overide prompted value)
*/ */
BINDABLE( setvar) { int setvar(int f, int n)
{
int status; /* status return */ int status; /* status return */
struct variable_description vd; /* variable num/type */ struct variable_description vd; /* variable num/type */
char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */ char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */
@ -1463,25 +1466,28 @@ static void mlforce( char *s) {
discmd = oldcmd; /* and restore the original setting */ discmd = oldcmd; /* and restore the original setting */
} }
/*
/* This function simply clears the message line, mainly for macro usage * This function simply clears the message line,
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
TBINDABLE( clrmes) { int clrmes( int f, int n) {
mlforce( "") ; mlforce( "") ;
return TRUE ; return TRUE ;
} }
/*
/* This function writes a string on the message line mainly for macro usage * This function writes a string on the message line
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
BINDABLE( writemsg) { int writemsg( int f, int n) {
char *buf ; /* buffer to receive message into */ int status ;
char *buf ; /* buffer to receive message into */
int status = newmlarg( &buf, "write-message: ", 0) ; status = newmlarg( &buf, "Message to write: ", 0) ;
if( status == TRUE) { if( status == TRUE) {
/* write the message out */ /* write the message out */
mlforce( buf) ; mlforce( buf) ;

28
eval.h
View File

@ -1,33 +1,29 @@
/* eval.h -- variables and operands evaluation */
#ifndef _EVAL_H_ #ifndef _EVAL_H_
# define _EVAL_H_ #define _EVAL_H_
#include "names.h"
#define DEBUGM 1 /* $debug triggers macro debugging */ #define DEBUGM 1 /* $debug triggers macro debugging */
# if DEBUGM #if DEBUGM
int mdbugout( char *fmt, ...) ; int mdbugout( char *fmt, ...) ;
# endif #endif
extern int macbug ; /* macro debuging flag */
extern int cmdstatus ; /* last command status */ extern int macbug ; /* macro debuging flag */
extern int rval ; /* return value of a subprocess */ extern int cmdstatus ; /* last command status */
extern long envram ; /* # of bytes current in use by malloc */ extern int rval ; /* return value of a subprocess */
extern long envram ; /* # of bytes current in use by malloc */
int readfirst_f( void) ; int readfirst_f( void) ;
int is_it_cmd( char *token) ; int is_it_cmd( char *token) ;
void varinit( void) ; void varinit( void) ;
int setvar( int f, int n) ;
const char *getval( char *token) ; const char *getval( char *token) ;
int stol( char *val) ; int stol( char *val) ;
char *mklower( char *str) ; char *mklower( char *str) ;
/* Bindable functions */ int clrmes( int f, int n) ;
TBINDABLE( clrmes) ; int writemsg( int f, int n) ;
BINDABLE( setvar) ;
BINDABLE( writemsg) ;
#endif #endif
/* end of eval.h */

831
exec.c

File diff suppressed because it is too large Load Diff

114
exec.h
View File

@ -1,65 +1,69 @@
/* exec.h -- bindable functions to execute functions, macros and procedures */
#ifndef _EXEC_H_ #ifndef _EXEC_H_
# define _EXEC_H_ #define _EXEC_H_
#include "names.h" #include "retcode.h"
extern boolean clexec ; /* command line execution flag */
int dofile( const char *fname) ; #define PROC 1 /* named procedures */
#if PROC
int storeproc( int f, int n) ;
int execproc( int f, int n) ;
#endif
extern boolean clexec ; /* command line execution flag */
int namedcmd( int f, int n) ;
int execcmd( int f, int n) ;
void gettoken( char *tok, int maxtoksize) ; void gettoken( char *tok, int maxtoksize) ;
boolean gettokval( char *tok, int maxtoksize) ; boolean gettokval( char *tok, int maxtoksize) ;
char *getnewtokval( void) ; char *getnewtokval( void) ;
int storemac( int f, int n) ;
int execbuf( int f, int n) ;
int execfile( int f, int n) ;
int dofile( const char *fname) ;
/* Bindable functions */ int cbuf1( int f, int n) ;
BINDABLE( execbuf) ; int cbuf2( int f, int n) ;
BINDABLE( execcmd) ; int cbuf3( int f, int n) ;
BINDABLE( execfile) ; int cbuf4( int f, int n) ;
BINDABLE( execproc) ; int cbuf5( int f, int n) ;
BINDABLE( namedcmd) ; int cbuf6( int f, int n) ;
BINDABLE( storemac) ; int cbuf7( int f, int n) ;
BINDABLE( storeproc) ; int cbuf8( int f, int n) ;
BINDABLE( cbuf1) ; int cbuf9( int f, int n) ;
BINDABLE( cbuf2) ; int cbuf10( int f, int n) ;
BINDABLE( cbuf3) ; int cbuf11( int f, int n) ;
BINDABLE( cbuf4) ; int cbuf12( int f, int n) ;
BINDABLE( cbuf5) ; int cbuf13( int f, int n) ;
BINDABLE( cbuf6) ; int cbuf14( int f, int n) ;
BINDABLE( cbuf7) ; int cbuf15( int f, int n) ;
BINDABLE( cbuf8) ; int cbuf16( int f, int n) ;
BINDABLE( cbuf9) ; int cbuf17( int f, int n) ;
BINDABLE( cbuf10) ; int cbuf18( int f, int n) ;
BINDABLE( cbuf11) ; int cbuf19( int f, int n) ;
BINDABLE( cbuf12) ; int cbuf20( int f, int n) ;
BINDABLE( cbuf13) ; int cbuf21( int f, int n) ;
BINDABLE( cbuf14) ; int cbuf22( int f, int n) ;
BINDABLE( cbuf15) ; int cbuf23( int f, int n) ;
BINDABLE( cbuf16) ; int cbuf24( int f, int n) ;
BINDABLE( cbuf17) ; int cbuf25( int f, int n) ;
BINDABLE( cbuf18) ; int cbuf26( int f, int n) ;
BINDABLE( cbuf19) ; int cbuf27( int f, int n) ;
BINDABLE( cbuf20) ; int cbuf28( int f, int n) ;
BINDABLE( cbuf21) ; int cbuf29( int f, int n) ;
BINDABLE( cbuf22) ; int cbuf30( int f, int n) ;
BINDABLE( cbuf23) ; int cbuf31( int f, int n) ;
BINDABLE( cbuf24) ; int cbuf32( int f, int n) ;
BINDABLE( cbuf25) ; int cbuf33( int f, int n) ;
BINDABLE( cbuf26) ; int cbuf34( int f, int n) ;
BINDABLE( cbuf27) ; int cbuf35( int f, int n) ;
BINDABLE( cbuf28) ; int cbuf36( int f, int n) ;
BINDABLE( cbuf29) ; int cbuf37( int f, int n) ;
BINDABLE( cbuf30) ; int cbuf38( int f, int n) ;
BINDABLE( cbuf31) ; int cbuf39( int f, int n) ;
BINDABLE( cbuf32) ; int cbuf40( int f, int n) ;
BINDABLE( cbuf33) ;
BINDABLE( cbuf34) ;
BINDABLE( cbuf35) ;
BINDABLE( cbuf36) ;
BINDABLE( cbuf37) ;
BINDABLE( cbuf38) ;
BINDABLE( cbuf39) ;
BINDABLE( cbuf40) ;
#endif #endif
/* end of exec.h */

35
file.c
View File

@ -1,11 +1,13 @@
/* file.c -- implements file.h */ /* file.c -- implements file.h */
#include "file.h" #include "file.h"
/* The routines in this file handle the reading, writing and lookup of disk /* file.c
files. All of details about the reading and writing of the disk are in *
"fileio.c". * The routines in this file handle the reading, writing
* and lookup of disk files. All of details about the
modified by Petri Kutvonen * reading and writing of the disk are in "fileio.c".
*
* modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -231,8 +233,8 @@ int getfile( const char *fname, boolean lockfl) {
return s; return s;
} }
/*
/* Read file "fname" into the current buffer, blowing away any text * Read file "fname" into the current buffer, blowing away any text
* found there. Called by both the read and find commands. Return * found there. Called by both the read and find commands. Return
* the final status of the read. Also called by the mainline, to * the final status of the read. Also called by the mainline, to
* read in a file specified on the command line as an argument. * read in a file specified on the command line as an argument.
@ -282,10 +284,10 @@ int readin(const char *fname, boolean lockfl)
/* read the file in */ /* read the file in */
mloutstr( "(Reading file)") ; mloutstr( "(Reading file)") ;
while( (s = ffgetline()) == FIOSUC) { while ((s = ffgetline()) == FIOSUC) {
line_p lp ; line_p lp ;
if( nline >= 10000000 /* Maximum # of lines from one file */ if( nline >= 10000000 /* MAXNLINE Maximum # of lines from one file */
|| (lp = lalloc( fpayload)) == NULL) { || (lp = lalloc( fpayload)) == NULL) {
s = FIOMEM ; /* Keep message on the */ s = FIOMEM ; /* Keep message on the */
break ; /* display. */ break ; /* display. */
@ -325,11 +327,12 @@ int readin(const char *fname, boolean lockfl)
if( fcode == FCODE_UTF_8) if( fcode == FCODE_UTF_8)
curbp->b_mode |= MDUTF8 ; curbp->b_mode |= MDUTF8 ;
if( s == FIOERR if( s == FIOERR) {
|| s == FIOMEM) { errmsg = "I/O ERROR, " ;
errmsg = (s == FIOERR) ? "I/O ERROR, " : "OUT OF MEMORY, " ; curbp->b_flag |= BFTRUNC ;
} else if( s == FIOMEM) {
errmsg = "OUT OF MEMORY, " ;
curbp->b_flag |= BFTRUNC ; curbp->b_flag |= BFTRUNC ;
curbp->b_mode |= MDVIEW ; /* force view mode as lost data */
} else } else
errmsg = "" ; errmsg = "" ;
@ -461,8 +464,10 @@ BINDABLE( filesave) {
/* complain about truncated files */ /* complain about truncated files */
if( (curbp->b_flag & BFTRUNC) != 0 if( (curbp->b_flag & BFTRUNC) != 0
&& mlyesno( "Truncated file ... write it out") == FALSE) && mlyesno("Truncated file ... write it out") == FALSE) {
return mloutfail( "(Aborted)") ; mloutfmt( "%B(Aborted)") ;
return FALSE ;
}
return writeout( curbp->b_fname) ; return writeout( curbp->b_fname) ;
} }

52
input.c
View File

@ -15,10 +15,9 @@
#include "bind.h" #include "bind.h"
#include "estruct.h" #include "estruct.h"
#include "bindable.h" #include "bindable.h"
#include "display.h" /* rubout(), echos(), echoc(), update() */ #include "display.h"
#include "exec.h" #include "exec.h"
#include "isa.h" #include "isa.h"
#include "mlout.h"
#include "names.h" #include "names.h"
#include "terminal.h" #include "terminal.h"
#include "utf8.h" #include "utf8.h"
@ -39,12 +38,12 @@ kbdstate kbdmode = STOP ; /* current keyboard macro mode */
int lastkey = 0 ; /* last keystoke */ int lastkey = 0 ; /* last keystoke */
int kbdrep = 0 ; /* number of repetitions */ int kbdrep = 0 ; /* number of repetitions */
int metac = CTL_ | '[' ; /* current meta character */ int metac = CTRL | '[' ; /* current meta character */
int ctlxc = CTL_ | 'X' ; /* current control X prefix char */ int ctlxc = CTRL | 'X' ; /* current control X prefix char */
int reptc = CTL_ | 'U' ; /* current universal repeat char */ int reptc = CTRL | 'U' ; /* current universal repeat char */
int abortc = CTL_ | 'G' ; /* current abort command char */ int abortc = CTRL | 'G' ; /* current abort command char */
const int nlc = CTL_ | 'J' ; /* end of input char */ const int nlc = CTRL | 'J' ; /* end of input char */
void ue_system( const char *cmd) { void ue_system( const char *cmd) {
@ -67,7 +66,7 @@ int mlyesno( const char *prompt)
for (;;) { for (;;) {
/* prompt the user */ /* prompt the user */
mloutfmt( "%s (y/n)? ", prompt) ; mlwrite( "%s (y/n)? ", prompt) ;
/* get the response */ /* get the response */
c = get1key() ; c = get1key() ;
@ -143,11 +142,11 @@ int newmlargt( char **outbufref, const char *prompt, int size) {
/* /*
* ectoc: * ectoc:
* expanded character to character * expanded character to character
* collapse the CTL_ and SPEC flags back into an ascii code * collapse the CTRL and SPEC flags back into an ascii code
*/ */
int ectoc( int c) { int ectoc( int c) {
if( c & CTL_) if( c & CTRL)
c ^= CTL_ | 0x40 ; c ^= CTRL | 0x40 ;
if( c & SPEC) if( c & SPEC)
c &= 255 ; c &= 255 ;
@ -190,10 +189,10 @@ nbind_p getname( void) {
/* and match it off */ /* and match it off */
return fncmatch( buf) ; return fncmatch( buf) ;
} else if( c == ectoc(abortc)) { /* Bell, abort */ } else if (c == ectoc(abortc)) { /* Bell, abort */
ctrlg( FALSE, 1) ; ctrlg(FALSE, 0);
TTflush() ; TTflush();
return NULL ; return NULL;
} else if (c == 0x7F || c == 0x08) { /* rubout/erase */ } else if (c == 0x7F || c == 0x08) { /* rubout/erase */
if (cpos != 0) { if (cpos != 0) {
@ -323,7 +322,7 @@ int tgetc(void)
} }
/* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC /* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC
and CTL_ prefixes. */ and CTRL prefixes. */
static int get1unicode( int *up) { static int get1unicode( int *up) {
/* Accept UTF-8 sequence */ /* Accept UTF-8 sequence */
int bytes ; int bytes ;
@ -344,7 +343,7 @@ static int get1unicode( int *up) {
bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ; bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ;
} else { } else {
if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */ if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CTL_ | 0x40 ; c ^= CTRL | 0x40 ;
*up = c ; *up = c ;
bytes = 1 ; bytes = 1 ;
@ -384,7 +383,7 @@ int getcmd( void) {
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 0x9B) if( c == 0x9B)
goto foundCSI ; goto foundCSI ;
else if( c == (CTL_ | '[')) { else if( c == (CTRL | '[')) {
/* fetch terminal sequence */ /* fetch terminal sequence */
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 'O') { /* F1 .. F4 */ if( c == 'O') { /* F1 .. F4 */
@ -408,7 +407,7 @@ int getcmd( void) {
mask = META ; mask = META ;
if( (v - 1) & 4) if( (v - 1) & 4)
mask |= CTL_ ; mask |= CTRL ;
v = v1 ; v = v1 ;
} }
@ -514,7 +513,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
quote_f = FALSE; quote_f = FALSE;
/* prompt the user for the input string */ /* prompt the user for the input string */
mloutstr( prompt); mlwrite( "%s", prompt);
for (;;) { for (;;) {
#if COMPLC #if COMPLC
@ -539,22 +538,23 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
} }
/* If it is a <ret>, change it to a <NL> */ /* If it is a <ret>, change it to a <NL> */
if( c == (CTL_ | 'M')) if( c == (CTRL | 'M'))
c = CTL_ | 0x40 | '\n' ; c = CTRL | 0x40 | '\n' ;
if( c == eolchar) { if( c == eolchar) {
/* if they hit the line terminator, wrap it up */ /* if they hit the line terminator, wrap it up */
buf[ cpos] = 0 ; buf[ cpos] = 0 ;
/* clear the message line */ /* clear the message line */
mloutstr( "") ; mlwrite("");
/* if we default the buffer, return FALSE */ /* if we default the buffer, return FALSE */
retval = cpos != 0 ; retval = cpos != 0 ;
break ; break ;
} else if( c == abortc) { } else if( c == abortc) {
/* Abort the input? */ /* Abort the input? */
retval = ctrlg( FALSE, 1) ; ctrlg( FALSE, 0) ;
retval = ABORT ;
break ; break ;
} }
@ -574,7 +574,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
} }
} else if( c == 0x15) { } else if( c == 0x15) {
/* C-U, kill */ /* C-U, kill */
mloutstr( prompt) ; mlwrite( "%s", prompt) ;
cpos = 0 ; cpos = 0 ;
#if COMPLC #if COMPLC
} else if( (c == 0x09 || c == ' ') && file_f) { } else if( (c == 0x09 || c == ' ') && file_f) {
@ -588,7 +588,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
didtry = 1; didtry = 1;
ocpos = cpos; ocpos = cpos;
mloutstr( prompt) ; mlwrite( "%s", prompt) ;
while( cpos != 0) { while( cpos != 0) {
c = buf[ --cpos] ; c = buf[ --cpos] ;
if( c == '*' || c == '?') { if( c == '*' || c == '?') {

View File

@ -1,7 +1,8 @@
/* isearch.c -- implements isearch.h */
#include "isearch.h" #include "isearch.h"
/* The functions in this file implement commands that perform incremental /* isearch.c
*
* The functions in this file implement commands that perform incremental
* searches in the forward and backward directions. This "ISearch" command * searches in the forward and backward directions. This "ISearch" command
* is intended to emulate the same command from the original EMACS * is intended to emulate the same command from the original EMACS
* implementation (ITS). Contains references to routines internal to * implementation (ITS). Contains references to routines internal to
@ -23,6 +24,7 @@
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
#include <stdio.h>
#include <string.h> #include <string.h>
#include "basic.h" #include "basic.h"
@ -40,6 +42,8 @@
/* /*
* Incremental search defines. * Incremental search defines.
*/ */
#if ISRCH
#define CMDBUFLEN 256 /* Length of our command buffer */ #define CMDBUFLEN 256 /* Length of our command buffer */
#define IS_ABORT 0x07 /* Abort the isearch */ #define IS_ABORT 0x07 /* Abort the isearch */
@ -56,7 +60,10 @@
/* IS_QUIT is no longer used, the variable metac is used instead */ /* IS_QUIT is no longer used, the variable metac is used instead */
static BINDABLE( isearch) ; /* internal use, not to be bound */ #endif
static int isearch( int f, int n) ;
static int checknext( char chr, char *patrn, int dir) ; static int checknext( char chr, char *patrn, int dir) ;
static int scanmore( char *patrn, int dir) ; static int scanmore( char *patrn, int dir) ;
static int match_pat( char *patrn) ; static int match_pat( char *patrn) ;
@ -66,6 +73,8 @@ static int uneat( void) ;
static void reeat( int c) ; static void reeat( int c) ;
#if ISRCH
static int echo_char(int c, int col); static int echo_char(int c, int col);
/* A couple of "own" variables for re-eat */ /* A couple of "own" variables for re-eat */
@ -80,10 +89,12 @@ static int cmd_offset; /* Current offset into command buff */
static int cmd_reexecute = -1; /* > 0 if re-executing command */ static int cmd_reexecute = -1; /* > 0 if re-executing command */
/* Subroutine to do incremental reverse search. It actually uses the /*
* Subroutine to do incremental reverse search. It actually uses the
* same code as the normal incremental search, as both can go both ways. * same code as the normal incremental search, as both can go both ways.
*/ */
BINDABLE( risearch) { int risearch(int f, int n)
{
struct line *curline; /* Current line on entry */ struct line *curline; /* Current line on entry */
int curoff; /* Current offset on entry */ int curoff; /* Current offset on entry */
@ -113,10 +124,11 @@ BINDABLE( risearch) {
return TRUE; return TRUE;
} }
/*
/* Again, but for the forward direction * Again, but for the forward direction
*/ */
BINDABLE( fisearch) { int fisearch(int f, int n)
{
struct line *curline; /* Current line on entry */ struct line *curline; /* Current line on entry */
int curoff; /* Current offset on entry */ int curoff; /* Current offset on entry */
@ -144,8 +156,8 @@ BINDABLE( fisearch) {
return TRUE; return TRUE;
} }
/*
/* Subroutine to do an incremental search. In general, this works similarly * Subroutine to do an incremental search. In general, this works similarly
* to the older micro-emacs search function, except that the search happens * to the older micro-emacs search function, except that the search happens
* as each character is typed, with the screen and cursor updated with each * as each character is typed, with the screen and cursor updated with each
* new search character. * new search character.
@ -170,7 +182,8 @@ BINDABLE( fisearch) {
* exists (or until the search is aborted). * exists (or until the search is aborted).
*/ */
static BINDABLE( isearch) { static int isearch(int f, int n)
{
int status; /* Search status */ int status; /* Search status */
int col; /* prompt column */ int col; /* prompt column */
unsigned cpos ; /* character number in search string */ unsigned cpos ; /* character number in search string */
@ -528,6 +541,8 @@ static void reeat(int c)
saved_get_char = term.t_getchar; /* Save the char get routine */ saved_get_char = term.t_getchar; /* Save the char get routine */
term.t_getchar = uneat; /* Replace it with ours */ term.t_getchar = uneat; /* Replace it with ours */
} }
#else
int isearch(int f, int n)
/* end of isearch.c */ {
}
#endif

View File

@ -1,11 +1,11 @@
/* isearch.h -- incremental search */
#ifndef __ISEARCH_H__ #ifndef __ISEARCH_H__
#define __ISEARCH_H__ #define __ISEARCH_H__
# include "names.h" /* BINDABLE */ #define ISRCH 1 /* Incremental searches like ITS EMACS */
BINDABLE( risearch) ; #if ISRCH
BINDABLE( fisearch) ; int risearch( int f, int n) ;
int fisearch( int f, int n) ;
#endif
#endif #endif
/* end of isearch */

12
line.c
View File

@ -249,11 +249,12 @@ void lchange(int flag)
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( insspace) { int insspace(int f, int n)
{
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
linsert( n, ' ') ; linsert(n, ' ');
backchar( f, n) ; backchar(f, n);
return TRUE ; return TRUE;
} }
/* /*
@ -820,7 +821,8 @@ BINDABLE( yank) {
* VIEW (read-only) mode * VIEW (read-only) mode
*/ */
boolean rdonly( void) { boolean rdonly( void) {
return mloutfail( "(Key illegal in VIEW mode)") ; mloutfmt( "%B(Key illegal in VIEW mode)") ;
return FALSE ;
} }
/* end of line.c */ /* end of line.c */

View File

@ -12,9 +12,4 @@ void mloutstr( const char *str) {
mloutfmt( (*str) ? "%s" : "", str) ; mloutfmt( (*str) ? "%s" : "", str) ;
} }
boolean mloutfail( const char *msg) {
mloutfmt( "%B%s", msg) ;
return FALSE ;
}
/* end of mlout.c */ /* end of mlout.c */

View File

@ -3,12 +3,9 @@
#ifndef __MLOUT_H__ #ifndef __MLOUT_H__
#define __MLOUT_H__ #define __MLOUT_H__
#include "retcode.h"
extern void (*mloutfmt)( const char *, ...) ; extern void (*mloutfmt)( const char *, ...) ;
void mloutstr( const char *str) ; void mloutstr( const char *str) ;
boolean mloutfail( const char *msg) ; /* output with BELL and return FALSE */
#endif /* __MLOUT_H__ */ #endif /* __MLOUT_H__ */

192
names.c
View File

@ -33,51 +33,51 @@
const name_bind names[] = { const name_bind names[] = {
{" abort-command", ctrlg, CTL_ | 'G'} , {" abort-command", ctrlg, CTRL | 'G'} ,
{" add-global-mode", setgmode, META | 'M'} , {" add-global-mode", setgmode, META | 'M'} ,
{" add-mode", setemode, CTLX | 'M'} , {" add-mode", setemode, CTLX | 'M'} ,
{" apropos", apro, META | 'A'} , {" apropos", apro, META | 'A'} ,
{" backward-character", (fnp_t) backchar, CTL_ | 'B'} , {" backward-character", (fnp_t) backchar, CTRL | 'B'} ,
{" begin-macro", (fnp_t) ctlxlp, CTLX | '('} , {" begin-macro", ctlxlp, CTLX | '('} ,
{" beginning-of-file", (fnp_t) gotobob, META | '<'} , {" beginning-of-file", (fnp_t) gotobob, META | '<'} ,
{" beginning-of-line", (fnp_t) gotobol, CTL_ | 'A'} , {" beginning-of-line", (fnp_t) gotobol, CTRL | 'A'} ,
{" bind-to-key", bindtokey, META | 'K'} , {" bind-to-key", bindtokey, META | 'K'} ,
{" buffer-position", showcpos, CTLX | '='} , {" buffer-position", showcpos, CTLX | '='} ,
{"!case-region-lower", lowerregion, CTLX | CTL_ | 'L'} , {"!case-region-lower", lowerregion, CTLX | CTRL | 'L'} ,
{"!case-region-upper", upperregion, CTLX | CTL_ | 'U'} , {"!case-region-upper", upperregion, CTLX | CTRL | 'U'} ,
{"!case-word-capitalize", capword, META | 'C'} , {"!case-word-capitalize", capword, META | 'C'} ,
{"!case-word-lower", lowerword, META | 'L'} , {"!case-word-lower", lowerword, META | 'L'} ,
{"!case-word-upper", upperword, META | 'U'} , {"!case-word-upper", upperword, META | 'U'} ,
{" change-file-name", filename, CTLX | 'N'} , {" change-file-name", filename, CTLX | 'N'} ,
{" change-screen-size", newsize, META | CTL_ | 'D'} , /* M^S */ {" change-screen-size", newsize, META | CTRL | 'D'} , /* M^S */
{" change-screen-width", newwidth, META | CTL_ | 'T'} , {" change-screen-width", newwidth, META | CTRL | 'T'} ,
{" clear-and-redraw", (fnp_t) redraw, CTL_ | 'L'} , {" clear-and-redraw", redraw, CTRL | 'L'} ,
{" clear-message-line", (fnp_t) clrmes, 0} , {" clear-message-line", clrmes, 0} ,
{" copy-region", copyregion, META | 'W'} , {" copy-region", copyregion, META | 'W'} ,
{" count-words", wordcount, META | CTL_ | 'C'} , {" count-words", wordcount, META | CTRL | 'C'} ,
{" ctlx-prefix", (fnp_t) cex, CTL_ | 'X'} , {" ctlx-prefix", cex, CTRL | 'X'} ,
{"!delete-blank-lines", deblank, CTLX | CTL_ | 'O'} , {"!delete-blank-lines", deblank, CTLX | CTRL | 'O'} ,
{" delete-buffer", killbuffer, CTLX | 'K'} , {" delete-buffer", killbuffer, CTLX | 'K'} ,
{" delete-global-mode", delgmode, META | CTL_ | 'M'} , {" delete-global-mode", delgmode, META | CTRL | 'M'} ,
{" delete-mode", delmode, CTLX | CTL_ | 'M'} , {" delete-mode", delmode, CTLX | CTRL | 'M'} ,
{"!delete-next-character", forwdel, CTL_ | 'D'} , {"!delete-next-character", forwdel, CTRL | 'D'} ,
{"!delete-next-word", delfword, META | 'D'} , {"!delete-next-word", delfword, META | 'D'} ,
{" delete-other-windows", onlywind, CTLX | '1'} , {" delete-other-windows", onlywind, CTLX | '1'} ,
{"!delete-previous-character", backdel, CTL_ | 'H'} , /* ^? */ {"!delete-previous-character", backdel, CTRL | 'H'} , /* ^? */
{"!delete-previous-word", delbword, META | CTL_ | 'H'} , /* M^? */ {"!delete-previous-word", delbword, META | CTRL | 'H'} , /* M^? */
{" delete-window", delwind, CTLX | '0'} , {" delete-window", delwind, CTLX | '0'} ,
{" describe-bindings", desbind, 0} , {" describe-bindings", desbind, 0} ,
{" describe-key", deskey, CTLX | '?'} , {" describe-key", deskey, CTLX | '?'} ,
{"!detab-line", detab, CTLX | CTL_ | 'D'} , /* X^A */ {"!detab-line", detab, CTLX | CTRL | 'D'} , /* X^A */
{" end-macro", (fnp_t) ctlxrp, CTLX | ')'} , {" end-macro", ctlxrp, CTLX | ')'} ,
{" end-of-file", (fnp_t) gotoeob, META | '>'} , {" end-of-file", (fnp_t) gotoeob, META | '>'} ,
{" end-of-line", (fnp_t) gotoeol, CTL_ | 'E'} , {" end-of-line", (fnp_t) gotoeol, CTRL | 'E'} ,
{"!entab-line", entab, CTLX | CTL_ | 'E'} , {"!entab-line", entab, CTLX | CTRL | 'E'} ,
{" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTL_ | 'X'} , {" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTRL | 'X'} ,
{" execute-buffer", execbuf, 0} , {" execute-buffer", execbuf, 0} ,
{" execute-command-line", execcmd, 0} , {" execute-command-line", execcmd, 0} ,
{" execute-file", execfile, 0} , {" execute-file", execfile, 0} ,
{" execute-macro", (fnp_t) ctlxe, CTLX | 'E'} , {" execute-macro", ctlxe, CTLX | 'E'} ,
{" execute-macro-1", cbuf1, 0} , {" execute-macro-1", cbuf1, 0} ,
{" execute-macro-10", cbuf10, 0} , {" execute-macro-10", cbuf10, 0} ,
{" execute-macro-11", cbuf11, 0} , {" execute-macro-11", cbuf11, 0} ,
@ -119,106 +119,116 @@ const name_bind names[] = {
{" execute-macro-8", cbuf8, 0} , {" execute-macro-8", cbuf8, 0} ,
{" execute-macro-9", cbuf9, 0} , {" execute-macro-9", cbuf9, 0} ,
{" execute-named-command", namedcmd, META | 'X'} , {" execute-named-command", namedcmd, META | 'X'} ,
{" execute-procedure", execproc, META | CTL_ | 'E'} , #if PROC
{" execute-procedure", execproc, META | CTRL | 'E'} ,
#endif
{" execute-program", execprg, CTLX | '$'} , {" execute-program", execprg, CTLX | '$'} ,
{" exit-emacs", quit, CTLX | CTL_ | 'C'} , {" exit-emacs", quit, CTLX | CTRL | 'C'} ,
{"!fill-paragraph", fillpara, META | 'Q'} , {"!fill-paragraph", fillpara, META | 'Q'} ,
{"!filter-buffer", filter_buffer, CTLX | '#'} , {"!filter-buffer", filter_buffer, CTLX | '#'} ,
{" find-file", filefind, CTLX | CTL_ | 'F'} , {" find-file", filefind, CTLX | CTRL | 'F'} ,
{" forward-character", (fnp_t) forwchar, CTL_ | 'F'} , {" forward-character", (fnp_t) forwchar, CTRL | 'F'} ,
{" goto-line", gotoline, META | 'G'} , {" goto-line", gotoline, META | 'G'} ,
#if CFENCE #if CFENCE
{" goto-matching-fence", getfence, META | CTL_ | 'F'} , {" goto-matching-fence", getfence, META | CTRL | 'F'} ,
#endif #endif
{" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */ {" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */
{"!handle-tab", insert_tab, CTL_ | 'I'} , {"!handle-tab", insert_tab, CTRL | 'I'} ,
{" help", help, META | '?'} , {" help", help, META | '?'} ,
{" hunt-backward", backhunt, 0} , {" hunt-backward", backhunt, 0} ,
{" hunt-forward", forwhunt, META | 'S'} , {" hunt-forward", forwhunt, META | 'S'} ,
{" i-shell", spawncli, CTLX | 'C'} , {" i-shell", spawncli, CTLX | 'C'} ,
#if ISRCH
{" incremental-search", fisearch, CTLX | 'S'} , {" incremental-search", fisearch, CTLX | 'S'} ,
{"!insert-file", insfile, CTLX | CTL_ | 'I'} , #endif
{"!insert-space", insspace, CTL_ | 'C'} , {"!insert-file", insfile, CTLX | CTRL | 'I'} ,
{"!insert-space", insspace, CTRL | 'C'} ,
{"!insert-string", istring, 0} , {"!insert-string", istring, 0} ,
#if PKCODE #if PKCODE
{"!justify-paragraph", justpara, META | 'J'} , {"!justify-paragraph", justpara, META | 'J'} ,
#endif #endif
{"!kill-paragraph", killpara, META | CTL_ | 'W'} , {"!kill-paragraph", killpara, META | CTRL | 'W'} ,
{"!kill-region", killregion, CTL_ | 'W'} , {"!kill-region", killregion, CTRL | 'W'} ,
{"!kill-to-end-of-line", killtext, CTL_ | 'K'} , {"!kill-to-end-of-line", killtext, CTRL | 'K'} ,
{" list-buffers", listbuffers, CTLX | CTL_ | 'B'} , {" list-buffers", listbuffers, CTLX | CTRL | 'B'} ,
{" meta-prefix", (fnp_t) metafn, CTL_ | '['} , {" meta-prefix", metafn, CTRL | '['} ,
{" move-window-down", mvdnwind, CTLX | CTL_ | 'N'} , {" move-window-down", mvdnwind, CTLX | CTRL | 'N'} ,
{" move-window-up", mvupwind, CTLX | CTL_ | 'P'} , {" move-window-up", mvupwind, CTLX | CTRL | 'P'} ,
{" name-buffer", namebuffer, META | CTL_ | 'N'} , {" name-buffer", namebuffer, META | CTRL | 'N'} ,
{"!newline", insert_newline, CTL_ | 'M'} , {"!newline", insert_newline, CTRL | 'M'} ,
{"!newline-and-indent", indent, CTL_ | 'J'} , {"!newline-and-indent", indent, CTRL | 'J'} ,
{" next-buffer", nextbuffer, CTLX | 'X'} , {" next-buffer", nextbuffer, CTLX | 'X'} ,
{" next-line", (fnp_t) forwline, CTL_ | 'N'} , {" next-line", (fnp_t) forwline, CTRL | 'N'} ,
{" next-page", (fnp_t) forwpage, CTL_ | 'V'} , {" next-page", (fnp_t) forwpage, CTRL | 'V'} ,
{" next-paragraph", gotoeop, META | 'N'} , {" next-paragraph", gotoeop, META | 'N'} ,
{" next-window", nextwind, CTLX | 'O'} , {" next-window", nextwind, CTLX | 'O'} ,
{" next-word", forwword, META | 'F'} , {" next-word", forwword, META | 'F'} ,
{" nop", (fnp_t) nullproc, META | SPEC | 'C'}, /* hook */ {" nop", nullproc, SPEC | META | 'C'}, /* hook */
{"!open-line", openline, CTL_ | 'O'} , {"!open-line", openline, CTRL | 'O'} ,
{"!overwrite-string", ovstring, 0} , {"!overwrite-string", ovstring, 0} ,
{" pipe-command", pipecmd, CTLX | '@'} , {" pipe-command", pipecmd, CTLX | '@'} ,
{" previous-line", (fnp_t) backline, CTL_ | 'P'} , {" previous-line", (fnp_t) backline, CTRL | 'P'} ,
{" previous-page", (fnp_t) backpage, CTL_ | 'Z'} , /* MV */ {" previous-page", (fnp_t) backpage, CTRL | 'Z'} , /* MV */
{" previous-paragraph", gotobop, META | 'P'} , {" previous-paragraph", gotobop, META | 'P'} ,
{" previous-window", prevwind, CTLX | 'P'} , {" previous-window", prevwind, CTLX | 'P'} ,
{" previous-word", backword, META | 'B'} , {" previous-word", backword, META | 'B'} ,
{"!query-replace-string", qreplace, META | CTL_ | 'R'} , {"!query-replace-string", qreplace, META | CTRL | 'R'} ,
{" quick-exit", quickexit, META | 'Z'} , {" quick-exit", quickexit, META | 'Z'} ,
{"!quote-character", quote, CTL_ | 'Q'} , {"!quote-character", quote, CTRL | 'Q'} , /* also XQ */
{"!read-file", fileread, CTLX | CTL_ | 'R'} , {"!read-file", fileread, CTLX | CTRL | 'R'} ,
{" redraw-display", (fnp_t) reposition, META | CTL_ | 'L'} , {" redraw-display", reposition, META | CTRL | 'L'} , /* M! */
{"!replace-string", sreplace, META | 'R'} , {"!replace-string", sreplace, META | 'R'} ,
{" resize-window", resize, CTLX | 'W'} , {" resize-window", resize, CTLX | 'W'} ,
{" restore-window", restwnd, 0} , {" restore-window", restwnd, 0} ,
#if ISRCH
{" reverse-incremental-search", risearch, CTLX | 'R'} , {" reverse-incremental-search", risearch, CTLX | 'R'} ,
{" run", execproc, 0} , /* alias of execute-procedure */ #endif
{"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */ #if PROC
{" run", execproc, 0} , // alias of execute-procedure
#endif
{"!save-file", filesave, CTLX | CTRL | 'S'} , /* also X^D */
{" save-window", savewnd, 0} , {" save-window", savewnd, 0} ,
{" scroll-next-down", scrnextdw, META | CTL_ | 'V'} , {" scroll-next-down", scrnextdw, META | CTRL | 'V'} ,
{" scroll-next-up", scrnextup, META | CTL_ | 'Z'} , {" scroll-next-up", scrnextup, META | CTRL | 'Z'} ,
{" search-forward", forwsearch, CTL_ | 'S'} , {" search-forward", forwsearch, CTRL | 'S'} ,
{" search-reverse", backsearch, CTL_ | 'R'} , {" search-reverse", backsearch, CTRL | 'R'} ,
{" select-buffer", usebuffer, CTLX | 'B'} , {" select-buffer", usebuffer, CTLX | 'B'} ,
{" set", setvar, CTLX | 'A'} , {" set", setvar, CTLX | 'A'} ,
{" set-fill-column", setfillcol, CTLX | 'F'} , {" set-fill-column", setfillcol, CTLX | 'F'} ,
{" set-mark", (fnp_t) setmark, META | ' '} , /* M. */ {" set-mark", (fnp_t) setmark, META | ' '} , /* M. */
{" shell-command", spawn, CTLX | '!'} , {" shell-command", spawn, CTLX | '!'} ,
{" shrink-window", shrinkwind, CTLX | CTL_ | 'Z'} , {" shrink-window", shrinkwind, CTLX | CTRL | 'Z'} ,
{" split-current-window", splitwind, CTLX | '2'} , {" split-current-window", splitwind, CTLX | '2'} ,
{" store-macro", storemac, 0} , {" store-macro", storemac, 0} ,
#if PROC
{" store-procedure", storeproc, 0} , {" store-procedure", storeproc, 0} ,
#endif
#if BSD | SVR4 #if BSD | SVR4
{" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */ {" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */
#endif #endif
{"!transpose-characters", (fnp_t) twiddle, CTL_ | 'T'} , {"!transpose-characters", (fnp_t) twiddle, CTRL | 'T'} ,
{"!trim-line", trim, CTLX | CTL_ | 'T'} , {"!trim-line", trim, CTLX | CTRL | 'T'} ,
{" unbind-key", unbindkey, META | CTL_ | 'K'} , {" unbind-key", unbindkey, META | CTRL | 'K'} ,
{" universal-argument", (fnp_t) unarg, CTL_ | 'U'} , {" universal-argument", unarg, CTRL | 'U'} ,
{" unmark-buffer", unmark, META | '~'} , {" unmark-buffer", unmark, META | '~'} ,
{" update-screen", upscreen, 0} , {" update-screen", upscreen, 0} ,
{" view-file", viewfile, CTLX | CTL_ | 'V'} , {" view-file", viewfile, CTLX | CTRL | 'V'} ,
{"!wrap-word", wrapword, META | SPEC | 'W'} , /* hook */ {"!wrap-word", wrapword, SPEC | META | 'W'} , /* hook */
{" write-file", filewrite, CTLX | CTL_ | 'W'} , {" write-file", filewrite, CTLX | CTRL | 'W'} ,
{" write-message", writemsg, 0} , {" write-message", writemsg, 0} ,
{"!yank", yank, CTL_ | 'Y'} , {"!yank", yank, CTRL | 'Y'} ,
{" ", NULL, 0}, {" ", NULL, 0},
/* extra key mapping */ /* extra key mapping */
// { NULL, newsize, META | CTL_ | 'S'}, // { NULL, newsize, META | CTRL | 'S'},
{ NULL, backdel, CTL_ | '?'}, { NULL, backdel, CTRL | '?'},
{ NULL, delbword, META | CTL_ | '?'}, { NULL, delbword, META | CTRL | '?'},
{ NULL, detab, CTLX | CTL_ | 'A'}, { NULL, detab, CTLX | CTRL | 'A'},
{ NULL, enlargewind, CTLX | '^'}, { NULL, enlargewind, CTLX | '^'},
{ NULL, (fnp_t) backpage, META | 'V'}, { NULL, (fnp_t) backpage, META | 'V'},
{ NULL, quote, CTLX | 'Q'}, { NULL, quote, CTLX | 'Q'},
{ NULL, (fnp_t) reposition, META | '!'}, { NULL, reposition, META | '!'},
//detab { NULL, filesave, CTLX | CTL_ | 'D'}, //detab { NULL, filesave, CTLX | CTRL | 'D'},
{ NULL, (fnp_t) setmark, META | '.'}, { NULL, (fnp_t) setmark, META | '.'},
// { NULL, bktoshell, META | 'S'}, // { NULL, bktoshell, META | 'S'},
@ -236,15 +246,15 @@ const name_bind names[] = {
{ NULL, help, SPEC | 'P'}, /* F1 */ { NULL, help, SPEC | 'P'}, /* F1 */
/* hooks */ /* hooks */
{ NULL, (fnp_t) nullproc, META | SPEC | 'R'}, /* hook */ { NULL, nullproc, SPEC | META | 'R'}, /* hook */
{ NULL, (fnp_t) nullproc, META | SPEC | 'X'}, /* hook */ { NULL, nullproc, SPEC | META | 'X'}, /* hook */
{ NULL, NULL, 0} { NULL, NULL, 0}
} ; } ;
static int lastnmidx = 0 ; /* index of last name entry */ static int lastnmidx = 0 ; /* index of last name entry */
kbind_p keytab ; kbind_p keytab ;
static int ktsize = 140 ; /* last check: need at least 133 + 1 */ static int ktsize = 140 ; /* last check: need at least 133 + 1 */
@ -272,9 +282,6 @@ boolean init_bindings( void) {
/* Add key definition */ /* Add key definition */
if( nbp->n_keycode) { if( nbp->n_keycode) {
kbind_p ktp = setkeybinding( nbp->n_keycode, nbp) ; kbind_p ktp = setkeybinding( nbp->n_keycode, nbp) ;
if( ktp->k_code == 0) /* Table full, no memory left */
return FALSE ;
/* check it was indeed an insertion at end of table not a /* check it was indeed an insertion at end of table not a
* key code re-definition */ * key code re-definition */
assert( (++ktp)->k_code == 0) ; assert( (++ktp)->k_code == 0) ;
@ -286,20 +293,14 @@ boolean init_bindings( void) {
/* Process extra key bindings if any */ /* Process extra key bindings if any */
for( nbp++ ; nbp->n_func != NULL ; nbp++) { for( nbp++ ; nbp->n_func != NULL ; nbp++) {
/* Check entry: a keycode and no name */ /* Check entry */
assert( nbp->n_keycode && (nbp->n_name == NULL)) ; assert( nbp->n_keycode && (nbp->n_name == NULL)) ;
/* Look for corresponding function and add extra key binding */ /* Look for corresponding function and add extra key binding */
nbind_p fnbp ; nbind_p fnbp ;
for( fnbp = names ; fnbp->n_func != NULL ; fnbp++) for( fnbp = names ; fnbp->n_func != NULL ; fnbp++)
if( fnbp->n_func == nbp->n_func) { if( fnbp->n_func == nbp->n_func) {
kbind_p ktp = setkeybinding( nbp->n_keycode, fnbp) ; setkeybinding( nbp->n_keycode, fnbp) ;
if( ktp->k_code == 0) /* Table full, no memory left */
return FALSE ;
/* check it was indeed an insertion at end of table not a
* key code re-definition */
assert( (++ktp)->k_code == 0) ;
break ; break ;
} }
@ -369,8 +370,8 @@ boolean delkeybinding( unsigned key) {
return FALSE ; return FALSE ;
} }
/*
/* This function looks a key binding up in the binding table * This function looks a key binding up in the binding table
* *
* int c; key to find what is bound to it * int c; key to find what is bound to it
*/ */
@ -415,26 +416,23 @@ nbind_p fncmatch( char *name) {
} }
/* user function that does NOTHING (bound to hooks) */ /* user function that does NOTHING */
TBINDABLE( nullproc) { BINDABLE( nullproc) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to meta prefix */ /* dummy function for binding to meta prefix */
TBINDABLE( metafn) { BINDABLE( metafn) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to control-x prefix */ /* dummy function for binding to control-x prefix */
TBINDABLE( cex) { BINDABLE( cex) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to universal-argument */ /* dummy function for binding to universal-argument */
TBINDABLE( unarg) { BINDABLE( unarg) {
return TRUE ; return TRUE ;
} }

19
names.h
View File

@ -1,10 +1,12 @@
/* names.h -- mapping of functions to names and keys */ /* names.h -- mapping of functions to names and keys */
#ifndef _NAMES_H_ #ifndef _NAMES_H_
# define _NAMES_H_ #define _NAMES_H_
#include "retcode.h" #include "retcode.h"
#define CTL_ 0x01000000 /* Control flag, or'ed in */
#define CTRL 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */ #define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */ #define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */ #define SPEC 0x08000000 /* special key (function keys) */
@ -12,9 +14,7 @@
/* Bindable uEMACS function pointer type and definition template */ /* Bindable uEMACS function pointer type and definition template */
#define BINDABLE( fname) int fname( boolean f, int n) #define BINDABLE( fname) int fname( int f, int n)
#define BBINDABLE( fname) boolean fname( boolean f, int n)
#define TBINDABLE BBINDABLE
typedef BINDABLE( (*fnp_t)) ; typedef BINDABLE( (*fnp_t)) ;
@ -53,10 +53,11 @@ nbind_p fncmatch( char *name) ; /* look up by name */
/* bindable functions mapped to prefix keys and hooks */ /* bindable functions mapped to prefix keys and hooks */
TBINDABLE( nullproc) ; BINDABLE( nullproc) ;
TBINDABLE( metafn) ; BINDABLE( metafn) ;
TBINDABLE( cex) ; BINDABLE( cex) ;
TBINDABLE( unarg) ; BINDABLE( unarg) ;
#endif #endif
/* end of names.h */ /* end of names.h */

View File

@ -144,13 +144,15 @@ int getcline(void)
return numlines + 1; return numlines + 1;
} }
/* Return current column. Stop at first non-blank given TRUE argument. /*
* Return current column. Stop at first non-blank given TRUE argument.
*/ */
int getccol( int bflg) { int getccol(int bflg)
int i, col ; {
int i, col;
line_p dlp = curwp->w_dotp ; line_p dlp = curwp->w_dotp ;
int byte_offset = curwp->w_doto ; int byte_offset = curwp->w_doto;
int len = llength( dlp) ; int len = llength(dlp);
col = i = 0; col = i = 0;
while (i < byte_offset) { while (i < byte_offset) {
@ -158,20 +160,17 @@ int getccol( int bflg) {
i += utf8_to_unicode(dlp->l_text, i, len, &c); i += utf8_to_unicode(dlp->l_text, i, len, &c);
if( bflg && c != ' ' && c != '\t') /* Request Stop at first non-blank */ if( bflg && c != ' ' && c != '\t') /* Request Stop at first non-blank */
break ; break;
if (c == '\t') if (c == '\t')
col += tabwidth - col % tabwidth ; col += tabwidth - col % tabwidth ;
else if (c < 0x20 || c == 0x7F) /* displayed as ^c */ else if (c < 0x20 || c == 0x7F) /* displayed as ^c */
col += 2 ; col += 2 ;
else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */ else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */
col += 3 ; col += 3 ;
else { else
int w = utf8_width( c) ; /* incomplete wc_width */ col += 1 ;
col += (w < 0) ? 2 : w ;
}
} }
return col;
return col ;
} }
/* /*
@ -715,40 +714,60 @@ BINDABLE( killtext) {
return ldelete(chunk, TRUE); return ldelete(chunk, TRUE);
} }
/*
/* prompt and set an editor mode * prompt and set an editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( setemode) { int setemode(int f, int n)
return adjustmode( TRUE, FALSE) ; {
#if PKCODE
return adjustmode(TRUE, FALSE);
#else
adjustmode(TRUE, FALSE);
#endif
} }
/*
/* prompt and delete an editor mode * prompt and delete an editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( delmode) { int delmode(int f, int n)
return adjustmode( FALSE, FALSE) ; {
#if PKCODE
return adjustmode(FALSE, FALSE);
#else
adjustmode(FALSE, FALSE);
#endif
} }
/*
/* prompt and set a global editor mode * prompt and set a global editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( setgmode) { int setgmode(int f, int n)
return adjustmode( TRUE, TRUE) ; {
#if PKCODE
return adjustmode(TRUE, TRUE);
#else
adjustmode(TRUE, TRUE);
#endif
} }
/*
/* prompt and delete a global editor mode * prompt and delete a global editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( delgmode) { int delgmode(int f, int n)
return adjustmode( FALSE, TRUE) ; {
#if PKCODE
return adjustmode(FALSE, TRUE);
#else
adjustmode(FALSE, TRUE);
#endif
} }
/* /*
@ -839,10 +858,11 @@ static int adjustmode( int kind, int global) {
static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) { static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) {
int status ; /* status return code */
char *tstring ; /* string to add */ char *tstring ; /* string to add */
/* ask for string to insert */ /* ask for string to insert */
int status = newmlargt( &tstring, prompt, 0) ; status = newmlargt( &tstring, prompt, 0) ; /* grab as big a token as screen allow */
if( tstring == NULL) if( tstring == NULL)
return status ; return status ;

View File

@ -9,7 +9,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stdio.h>
#include "buffer.h" #include "buffer.h"
#include "estruct.h" #include "estruct.h"
@ -139,9 +139,10 @@ int getregion( region_p rp) {
line_p flp, blp ; line_p flp, blp ;
long fsize, bsize ; long fsize, bsize ;
if (curwp->w_markp == NULL) if (curwp->w_markp == NULL) {
return mloutfail( "No mark set in this window") ; mloutstr( "No mark set in this window") ;
return FALSE;
}
if (curwp->w_dotp == curwp->w_markp) { if (curwp->w_dotp == curwp->w_markp) {
rp->r_linep = curwp->w_dotp; rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko) { if (curwp->w_doto < curwp->w_marko) {
@ -181,8 +182,8 @@ int getregion( region_p rp) {
} }
} }
} }
mloutstr( "Bug: lost mark") ;
return mloutfail( "Bug: lost mark") ; return FALSE;
} }
/* end of region.c */ /* end of region.c */

View File

@ -1,7 +1,9 @@
/* search.c -- implements search.h */ /* search.c -- implements search.h */
#include "search.h" #include "search.h"
/* The functions in this file implement commands that search in the forward /* search.c
*
* The functions in this file implement commands that search in the forward
* and backward directions. There are no special characters in the search * and backward directions. There are no special characters in the search
* strings. Probably should have a regular expression search, or something * strings. Probably should have a regular expression search, or something
* like that. * like that.
@ -175,14 +177,15 @@ static int biteq(int bc, char *cclmap);
static char *clearbits(void); static char *clearbits(void);
static void setbit(int bc, char *cclmap); static void setbit(int bc, char *cclmap);
/*
/* forwsearch -- Search forward. Get a search string from the user, and * forwsearch -- Search forward. Get a search string from the user, and
* search for the string. If found, reset the "." to be just after * search for the string. If found, reset the "." to be just after
* the match string, and (perhaps) repaint the display. * the match string, and (perhaps) repaint the display.
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( forwsearch) { int forwsearch(int f, int n)
{
int status = TRUE; int status = TRUE;
/* If n is negative, search backwards. /* If n is negative, search backwards.
@ -220,14 +223,15 @@ BINDABLE( forwsearch) {
return status; return status;
} }
/*
/* forwhunt -- Search forward for a previously acquired search string. * forwhunt -- Search forward for a previously acquired search string.
* If found, reset the "." to be just after the match string, * If found, reset the "." to be just after the match string,
* and (perhaps) repaint the display. * and (perhaps) repaint the display.
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( forwhunt) { int forwhunt(int f, int n)
{
int status = TRUE; int status = TRUE;
if (n < 0) /* search backwards */ if (n < 0) /* search backwards */
@ -272,15 +276,16 @@ BINDABLE( forwhunt) {
return status; return status;
} }
/*
/* backsearch -- Reverse search. Get a search string from the user, and * backsearch -- Reverse search. Get a search string from the user, and
* search, starting at "." and proceeding toward the front of the buffer. * search, starting at "." and proceeding toward the front of the buffer.
* If found "." is left pointing at the first character of the pattern * If found "." is left pointing at the first character of the pattern
* (the last character that was matched). * (the last character that was matched).
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( backsearch) { int backsearch(int f, int n)
{
int status = TRUE; int status = TRUE;
/* If n is negative, search forwards. /* If n is negative, search forwards.
@ -319,15 +324,16 @@ BINDABLE( backsearch) {
return status; return status;
} }
/*
/* backhunt -- Reverse search for a previously acquired search string, * backhunt -- Reverse search for a previously acquired search string,
* starting at "." and proceeding toward the front of the buffer. * starting at "." and proceeding toward the front of the buffer.
* If found "." is left pointing at the first character of the pattern * If found "." is left pointing at the first character of the pattern
* (the last character that was matched). * (the last character that was matched).
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( backhunt) { int backhunt(int f, int n)
{
int status = TRUE; int status = TRUE;
if (n < 0) if (n < 0)
@ -782,24 +788,26 @@ void rvstrcpy(char *rvstr, char *str)
*rvstr = '\0'; *rvstr = '\0';
} }
/*
/* sreplace -- Search and replace. * sreplace -- Search and replace.
* *
* int f; default flag * int f; default flag
* int n; # of repetitions wanted * int n; # of repetitions wanted
*/ */
BINDABLE( sreplace) { int sreplace(int f, int n)
return replaces( FALSE, f, n) ; {
return replaces(FALSE, f, n);
} }
/*
/* qreplace -- search and replace with query. * qreplace -- search and replace with query.
* *
* int f; default flag * int f; default flag
* int n; # of repetitions wanted * int n; # of repetitions wanted
*/ */
BINDABLE( qreplace) { int qreplace(int f, int n)
return replaces( TRUE, f, n) ; {
return replaces(TRUE, f, n);
} }
/* /*

39
spawn.c
View File

@ -1,7 +1,9 @@
/* spawn.c -- implements spawn.h */ /* spawn.c -- implements spawn.h */
#include "spawn.h" #include "spawn.h"
/* Various operating system access commands. /* spawn.c
*
* Various operating system access commands.
* *
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
@ -32,11 +34,13 @@
#endif #endif
/* Create a subjob with a copy of the command intrepreter in it. When the /*
* Create a subjob with a copy of the command intrepreter in it. When the
* command interpreter exits, mark the screen as garbage so that you do a full * command interpreter exits, mark the screen as garbage so that you do a full
* repaint. Bound to "^X C". * repaint. Bound to "^X C".
*/ */
BINDABLE( spawncli) { int spawncli(int f, int n)
{
#if USG | BSD #if USG | BSD
char *cp; char *cp;
#endif #endif
@ -77,8 +81,9 @@ BINDABLE( spawncli) {
} }
#if BSD | SVR4 #if BSD | SVR4
/* suspend MicroEMACS and wait to wake up */
BINDABLE( bktoshell) { int bktoshell(int f, int n)
{ /* suspend MicroEMACS and wait to wake up */
vttidy(); vttidy();
/****************************** /******************************
int pid; int pid;
@ -98,12 +103,12 @@ void rtfrmshell(void)
} }
#endif #endif
/*
/* Run a one-liner in a subjob. When the command returns, wait for a single * Run a one-liner in a subjob. When the command returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is * character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X !". * done. Bound to "C-X !".
*/ */
BINDABLE( spawn) { int spawn( int f, int n) {
int s ; int s ;
char *line ; char *line ;
@ -136,13 +141,13 @@ BINDABLE( spawn) {
#endif #endif
} }
/*
/* Run an external program with arguments. When it returns, wait for a single * Run an external program with arguments. When it returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is * character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X $". * done. Bound to "C-X $".
*/ */
BINDABLE( execprg) { int execprg( int f, int n) {
int s ; int s ;
char *line ; char *line ;
@ -171,11 +176,11 @@ BINDABLE( execprg) {
#endif #endif
} }
/*
/* Pipe a one line command into a window * Pipe a one line command into a window
* Bound to ^X @ * Bound to ^X @
*/ */
BINDABLE( pipecmd) { int pipecmd( int f, int n) {
int s ; /* return status from CLI */ int s ; /* return status from CLI */
struct window *wp ; /* pointer to new window */ struct window *wp ; /* pointer to new window */
buffer_p bp ; /* pointer to buffer to zot */ buffer_p bp ; /* pointer to buffer to zot */
@ -266,11 +271,11 @@ BINDABLE( pipecmd) {
return TRUE; return TRUE;
} }
/*
/* filter a buffer through an external DOS program * filter a buffer through an external DOS program
* Bound to ^X # * Bound to ^X #
*/ */
BINDABLE( filter_buffer) { int filter_buffer( int f, int n) {
int s ; /* return status from CLI */ int s ; /* return status from CLI */
buffer_p bp ; /* pointer to buffer to zot */ buffer_p bp ; /* pointer to buffer to zot */
char *mlarg ; char *mlarg ;

25
util.c
View File

@ -1,20 +1,17 @@
/* util.c -- implements util.h */
#include "util.h" #include "util.h"
/* Safe zeroing, no complaining about overlap */ /* Safe zeroing, no complaining about overlap */
void mystrscpy( char *dst, const char *src, int size) { void mystrscpy(char *dst, const char *src, int size)
if( size <= 0) {
return ; if (!size)
return;
while( --size) { while (--size) {
char c = *src++ ; char c = *src++;
if( !c) if (!c)
break ; break;
*dst++ = c;
*dst++ = c ;
} }
*dst = 0;
*dst = 0 ;
} }
/* end of util.c */

6
util.h
View File

@ -1,9 +1,7 @@
/* util.h -- utility functions */
#ifndef UTIL_H_ #ifndef UTIL_H_
# define UTIL_H_ #define UTIL_H_
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void mystrscpy( char *dst, const char *src, int size) ; void mystrscpy(char *dst, const char *src, int size);
#endif /* UTIL_H_ */ #endif /* UTIL_H_ */
/* end of util.h */

317
window.c
View File

@ -1,65 +1,77 @@
/* window.c -- inplements window.h */ /* window.c -- inplements window.h */
#include "window.h" #include "window.h"
/* Window management. Some of the functions are internal, and some are /* window.c
attached to keys that the user actually types. *
* Window management. Some of the functions are internal, and some are
* attached to keys that the user actually types.
*
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include "basic.h" #include "basic.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* upmode() */ #include "display.h"
#include "estruct.h" #include "estruct.h"
#include "execute.h" #include "execute.h"
#include "line.h" #include "line.h"
#include "mlout.h"
#include "terminal.h" #include "terminal.h"
#include "wrapper.h" #include "wrapper.h"
window_p curwp ; /* Current window */
window_p wheadp ; /* Head of list of windows */
static window_p savwindow = NULL ; /* saved window pointer */ struct window *curwp ; /* Current window */
struct window *wheadp ; /* Head of list of windows */
static struct window *swindow = NULL ; /* saved window pointer */
/* Reposition dot in the current window to line "n". If the argument is /*
positive, it is that line. If it is negative it is that line from the * Reposition dot in the current window to line "n". If the argument is
bottom. If it is 0 the window is centered (this is what the standard * positive, it is that line. If it is negative it is that line from the
redisplay code does). With no argument it defaults to 0. Bound to M-!. * bottom. If it is 0 the window is centered (this is what the standard
* redisplay code does). With no argument it defaults to 0. Bound to M-!.
*/ */
TBINDABLE( reposition) { int reposition(int f, int n)
curwp->w_force = (f == FALSE) ? 0 : n ; /* default to 0 to center screen */ {
curwp->w_flag |= WFFORCE ; if (f == FALSE) /* default to 0 to center screen */
return TRUE ; n = 0;
curwp->w_force = n;
curwp->w_flag |= WFFORCE;
return TRUE;
} }
/*
/* Refresh the screen. With no argument, it just does the refresh. With * Refresh the screen. With no argument, it just does the refresh. With an
an argument it recenters "." in the current window. Bound to "C-L". * argument it recenters "." in the current window. Bound to "C-L".
*/ */
TBINDABLE( redraw) { int redraw(int f, int n)
if( f == FALSE) {
sgarbf = TRUE ; if (f == FALSE)
sgarbf = TRUE;
else { else {
curwp->w_force = 0 ; /* Center dot. */ curwp->w_force = 0; /* Center dot. */
curwp->w_flag |= WFFORCE ; curwp->w_flag |= WFFORCE;
} }
return TRUE ; return TRUE;
} }
/*
/* The command make the next window (next => down the screen) the current * The command make the next window (next => down the screen) the current
window. There are no real errors, although the command does nothing if * window. There are no real errors, although the command does nothing if
there is only 1 window on the screen. Bound to "C-X C-N". * there is only 1 window on the screen. Bound to "C-X C-N".
*
with an argument this command finds the <n>th window from the top * with an argument this command finds the <n>th window from the top
*
int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*
*/ */
BINDABLE( nextwind) { int nextwind(int f, int n)
window_p wp; {
struct window *wp;
int nwindows; /* total number of windows */ int nwindows; /* total number of windows */
if (f) { if (f) {
@ -82,8 +94,10 @@ BINDABLE( nextwind) {
wp = wheadp; wp = wheadp;
while (--n) while (--n)
wp = wp->w_wndp; wp = wp->w_wndp;
} else } else {
return mloutfail( "Window number out of range") ; mlwrite("Window number out of range");
return FALSE;
}
} else if ((wp = curwp->w_wndp) == NULL) } else if ((wp = curwp->w_wndp) == NULL)
wp = wheadp; wp = wheadp;
curwp = wp; curwp = wp;
@ -93,14 +107,15 @@ BINDABLE( nextwind) {
return TRUE; return TRUE;
} }
/*
/* This command makes the previous window (previous => up the screen) the * This command makes the previous window (previous => up the screen) the
current window. There arn't any errors, although the command does not * current window. There arn't any errors, although the command does not do a
do a lot if there is 1 window. * lot if there is 1 window.
*/ */
BINDABLE( prevwind) { int prevwind(int f, int n)
window_p wp1; {
window_p wp2; struct window *wp1;
struct window *wp2;
/* if we have an argument, we mean the nth window from the bottom */ /* if we have an argument, we mean the nth window from the bottom */
if (f) if (f)
@ -122,26 +137,28 @@ BINDABLE( prevwind) {
return TRUE; return TRUE;
} }
/*
/* This command moves the current window down by "arg" lines. Recompute the * This command moves the current window down by "arg" lines. Recompute the
* top line in the window. The move up and move down code is almost completely * top line in the window. The move up and move down code is almost completely
* the same; most of the work has to do with reframing the window, and picking * the same; most of the work has to do with reframing the window, and picking
* a new dot. We share the code by having "move down" just be an interface to * a new dot. We share the code by having "move down" just be an interface to
* "move up". Magic. Bound to "C-X C-N". * "move up". Magic. Bound to "C-X C-N".
*/ */
BINDABLE( mvdnwind) { int mvdnwind(int f, int n)
return mvupwind( f, -n) ; {
return mvupwind(f, -n);
} }
/*
/* Move the current window up by "arg" lines. Recompute the new top line of * Move the current window up by "arg" lines. Recompute the new top line of
* the window. Look to see if "." is still on the screen. If it is, you win. * the window. Look to see if "." is still on the screen. If it is, you win.
* If it isn't, then move "." to center it in the new framing of the window * If it isn't, then move "." to center it in the new framing of the window
* (this command does not really move "."; it moves the frame). Bound to * (this command does not really move "."; it moves the frame). Bound to
* "C-X C-P". * "C-X C-P".
*/ */
BINDABLE( mvupwind) { int mvupwind(int f, int n)
line_p lp; {
struct line *lp;
int i; int i;
lp = curwp->w_linep; lp = curwp->w_linep;
@ -176,16 +193,17 @@ BINDABLE( mvupwind) {
return TRUE; return TRUE;
} }
/*
/* This command makes the current window the only window on the screen. Bound * This command makes the current window the only window on the screen. Bound
* to "C-X 1". Try to set the framing so that "." does not have to move on the * to "C-X 1". Try to set the framing so that "." does not have to move on the
* display. Some care has to be taken to keep the values of dot and mark in * display. Some care has to be taken to keep the values of dot and mark in
* the buffer structures right if the distruction of a window makes a buffer * the buffer structures right if the distruction of a window makes a buffer
* become undisplayed. * become undisplayed.
*/ */
BINDABLE( onlywind) { int onlywind(int f, int n)
window_p wp; {
line_p lp; struct window *wp;
struct line *lp;
int i; int i;
while (wheadp != curwp) { while (wheadp != curwp) {
@ -223,20 +241,23 @@ BINDABLE( onlywind) {
return TRUE; return TRUE;
} }
/*
/* Delete the current window, placing its space in the window above, * Delete the current window, placing its space in the window above,
* or, if it is the top window, the window below. Bound to C-X 0. * or, if it is the top window, the window below. Bound to C-X 0.
* *
* int f, n; arguments are ignored for this command * int f, n; arguments are ignored for this command
*/ */
BINDABLE( delwind) { int delwind(int f, int n)
window_p wp; /* window to recieve deleted space */ {
window_p lwp; /* ptr window before curwp */ struct window *wp; /* window to recieve deleted space */
struct window *lwp; /* ptr window before curwp */
int target; /* target line to search for */ int target; /* target line to search for */
/* if there is only one window, don't delete it */ /* if there is only one window, don't delete it */
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Can not delete this window") ; mlwrite("Can not delete this window");
return FALSE;
}
/* find window before curwp in linked list */ /* find window before curwp in linked list */
wp = wheadp; wp = wheadp;
@ -295,8 +316,8 @@ BINDABLE( delwind) {
return TRUE; return TRUE;
} }
/*
/* Split the current window. A window smaller than 3 lines cannot be * Split the current window. A window smaller than 3 lines cannot be
* split. An argument of 1 forces the cursor into the upper window, an * split. An argument of 1 forces the cursor into the upper window, an
* argument of two forces the cursor to the lower window. The only * argument of two forces the cursor to the lower window. The only
* other error that is possible is a "malloc" failure allocating the * other error that is possible is a "malloc" failure allocating the
@ -304,21 +325,21 @@ BINDABLE( delwind) {
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( splitwind) { int splitwind(int f, int n)
window_p wp; {
line_p lp; struct window *wp;
struct line *lp;
int ntru; int ntru;
int ntrl; int ntrl;
int ntrd; int ntrd;
window_p wp1; struct window *wp1;
window_p wp2; struct window *wp2;
if( curwp->w_ntrows < 3) { if (curwp->w_ntrows < 3) {
mloutfmt( "Cannot split a %d line window", curwp->w_ntrows) ; mlwrite("Cannot split a %d line window", curwp->w_ntrows);
return FALSE ; return FALSE;
} }
wp = xmalloc(sizeof(struct window));
wp = xmalloc( sizeof *wp) ;
++curbp->b_nwnd; /* Displayed twice. */ ++curbp->b_nwnd; /* Displayed twice. */
wp->w_bufp = curbp; wp->w_bufp = curbp;
wp->w_dotp = curwp->w_dotp; wp->w_dotp = curwp->w_dotp;
@ -377,30 +398,33 @@ BINDABLE( splitwind) {
return TRUE; return TRUE;
} }
/*
/* Enlarge the current window. Find the window that loses space. Make sure it * Enlarge the current window. Find the window that loses space. Make sure it
* is big enough. If so, hack the window descriptions, and ask redisplay to do * is big enough. If so, hack the window descriptions, and ask redisplay to do
* all the hard work. You don't just set "force reframe" because dot would * all the hard work. You don't just set "force reframe" because dot would
* move. Bound to "C-X Z". * move. Bound to "C-X Z".
*/ */
BINDABLE( enlargewind) { int enlargewind(int f, int n)
window_p adjwp; {
line_p lp; struct window *adjwp;
struct line *lp;
int i; int i;
if (n < 0) if (n < 0)
return shrinkwind(f, -n); return shrinkwind(f, -n);
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Only one window") ; mlwrite("Only one window");
return FALSE;
}
if ((adjwp = curwp->w_wndp) == NULL) { if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp; adjwp = wheadp;
while (adjwp->w_wndp != curwp) while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp; adjwp = adjwp->w_wndp;
} }
if( adjwp->w_ntrows <= n) if (adjwp->w_ntrows <= n) {
return mloutfail( "Impossible change") ; mlwrite("Impossible change");
return FALSE;
}
if (curwp->w_wndp == adjwp) { /* Shrink below. */ if (curwp->w_wndp == adjwp) { /* Shrink below. */
lp = adjwp->w_linep; lp = adjwp->w_linep;
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i) for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
@ -426,29 +450,32 @@ BINDABLE( enlargewind) {
return TRUE; return TRUE;
} }
/*
/* Shrink the current window. Find the window that gains space. Hack at the * Shrink the current window. Find the window that gains space. Hack at the
* window descriptions. Ask the redisplay to do all the hard work. Bound to * window descriptions. Ask the redisplay to do all the hard work. Bound to
* "C-X C-Z". * "C-X C-Z".
*/ */
BINDABLE( shrinkwind) { int shrinkwind(int f, int n)
window_p adjwp; {
line_p lp; struct window *adjwp;
struct line *lp;
int i; int i;
if (n < 0) if (n < 0)
return enlargewind(f, -n); return enlargewind(f, -n);
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Only one window") ; mlwrite("Only one window");
return FALSE;
}
if ((adjwp = curwp->w_wndp) == NULL) { if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp; adjwp = wheadp;
while (adjwp->w_wndp != curwp) while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp; adjwp = adjwp->w_wndp;
} }
if( curwp->w_ntrows <= n) if (curwp->w_ntrows <= n) {
return mloutfail( "Impossible change") ; mlwrite("Impossible change");
return FALSE;
}
if (curwp->w_wndp == adjwp) { /* Grow below. */ if (curwp->w_wndp == adjwp) { /* Grow below. */
lp = adjwp->w_linep; lp = adjwp->w_linep;
for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep;
@ -475,12 +502,13 @@ BINDABLE( shrinkwind) {
return TRUE; return TRUE;
} }
/*
/* Resize the current window to the requested size * Resize the current window to the requested size
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( resize) { int resize(int f, int n)
{
int clines; /* current # of lines in window */ int clines; /* current # of lines in window */
/* must have a non-default argument, else ignore call */ /* must have a non-default argument, else ignore call */
@ -497,14 +525,14 @@ BINDABLE( resize) {
return enlargewind(TRUE, n - clines); return enlargewind(TRUE, n - clines);
} }
/*
/* Pick a window for a pop-up. Split the screen if there is only one window. * Pick a window for a pop-up. Split the screen if there is only one window.
* Pick the uppermost window that isn't the current window. An LRU algorithm * Pick the uppermost window that isn't the current window. An LRU algorithm
* might be better. Return a pointer, or NULL on error. * might be better. Return a pointer, or NULL on error.
*/ */
window_p wpopup(void) struct window *wpopup(void)
{ {
window_p wp; struct window *wp;
if (wheadp->w_wndp == NULL /* Only 1 window */ if (wheadp->w_wndp == NULL /* Only 1 window */
&& splitwind(FALSE, 0) == FALSE) /* and it won't split */ && splitwind(FALSE, 0) == FALSE) /* and it won't split */
@ -515,57 +543,59 @@ window_p wpopup(void)
return wp; return wp;
} }
int scrnextup(int f, int n)
/* scroll the next window up (back) a page */ { /* scroll the next window up (back) a page */
BINDABLE( scrnextup) {
nextwind(FALSE, 1); nextwind(FALSE, 1);
backpage(f, n); backpage(f, n);
prevwind(FALSE, 1); prevwind(FALSE, 1);
return TRUE; return TRUE;
} }
int scrnextdw(int f, int n)
/* scroll the next window down (forward) a page */ { /* scroll the next window down (forward) a page */
BINDABLE( scrnextdw) {
nextwind(FALSE, 1); nextwind(FALSE, 1);
forwpage(f, n); forwpage(f, n);
prevwind(FALSE, 1); prevwind(FALSE, 1);
return TRUE; return TRUE;
} }
int savewnd(int f, int n)
/* save ptr to current window */ { /* save ptr to current window */
BINDABLE( savewnd) { swindow = curwp;
savwindow = curwp ; return TRUE;
return TRUE ;
} }
int restwnd(int f, int n)
{ /* restore the saved screen */
struct window *wp;
/* restore the saved screen */ /* find the window */
BINDABLE( restwnd) { wp = wheadp;
/* check the saved window still exists */ while (wp != NULL) {
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { if (wp == swindow) {
if( wp == savwindow) { curwp = wp;
curwp = wp ; curbp = wp->w_bufp;
curbp = wp->w_bufp ; upmode();
upmode() ; return TRUE;
return TRUE ;
} }
wp = wp->w_wndp;
} }
return mloutfail( "(No such window exists)") ; mlwrite("(No such window exists)");
return FALSE;
} }
/*
/* resize the screen, re-writing the screen * resize the screen, re-writing the screen
* *
* int f; default flag * int f; default flag
* int n; numeric argument * int n; numeric argument
*/ */
BINDABLE( newsize) { int newsize(int f, int n)
window_p wp; /* current window being examined */ {
window_p nextwp; /* next window to scan */ struct window *wp; /* current window being examined */
window_p lastwp; /* last window scanned */ struct window *nextwp; /* next window to scan */
struct window *lastwp; /* last window scanned */
int lastline; /* screen line of last line of current window */ int lastline; /* screen line of last line of current window */
/* if the command defaults, assume the largest */ /* if the command defaults, assume the largest */
@ -573,8 +603,10 @@ BINDABLE( newsize) {
n = term.t_mrow ; n = term.t_mrow ;
/* make sure it's in range */ /* make sure it's in range */
if( n < 3 || n > term.t_mrow) if (n < 3 || n > term.t_mrow) {
return mloutfail( "%%Screen size out of range") ; mlwrite("%%Screen size out of range");
return FALSE;
}
if (term.t_nrow == n - 1) if (term.t_nrow == n - 1)
return TRUE; return TRUE;
@ -642,22 +674,25 @@ BINDABLE( newsize) {
return TRUE; return TRUE;
} }
/*
/* resize the screen, re-writing the screen * resize the screen, re-writing the screen
* *
* int f; default flag * int f; default flag
* int n; numeric argument * int n; numeric argument
*/ */
BINDABLE( newwidth) { int newwidth(int f, int n)
window_p wp; {
struct window *wp;
/* if the command defaults, assume the largest */ /* if the command defaults, assume the largest */
if (f == FALSE) if (f == FALSE)
n = term.t_mcol; n = term.t_mcol;
/* make sure it's in range */ /* make sure it's in range */
if (n < 10 || n > term.t_mcol) if (n < 10 || n > term.t_mcol) {
return mloutfail( "%%Screen width out of range") ; mlwrite("%%Screen width out of range");
return FALSE;
}
/* otherwise, just re-width it (no big deal) */ /* otherwise, just re-width it (no big deal) */
term.t_ncol = n; term.t_ncol = n;
@ -678,7 +713,7 @@ BINDABLE( newwidth) {
int getwpos(void) int getwpos(void)
{ /* get screen offset of current line in current window */ { /* get screen offset of current line in current window */
int sline; /* screen line from top of window */ int sline; /* screen line from top of window */
line_p lp; /* scannile line pointer */ struct line *lp; /* scannile line pointer */
/* search down the line we want */ /* search down the line we want */
lp = curwp->w_linep; lp = curwp->w_linep;
@ -696,5 +731,3 @@ void cknewwindow(void)
{ {
execute(META | SPEC | 'X', FALSE, 1); execute(META | SPEC | 'X', FALSE, 1);
} }
/* end of window.c */

View File

@ -1,35 +1,34 @@
/* window.h -- window functionality */
#ifndef _WINDOW_H_ #ifndef _WINDOW_H_
#define _WINDOW_H_ #define _WINDOW_H_
#include "defines.h" /* COLOR, SCROLLCODE */ #include "defines.h" /* COLOR, SCROLLCODE */
#include "buffer.h" /* buffer_p, line_p */ #include "buffer.h" /* buffer, line */
#include "names.h" /* BINDABLE() */
/* There is a window structure allocated for every active display window. /*
The windows are kept in a big list, in top to bottom screen order, with * There is a window structure allocated for every active display window. The
the listhead at "wheadp". Each window contains its own values of dot * windows are kept in a big list, in top to bottom screen order, with the
and mark. The flag field contains some bits that are set by commands to * listhead at "wheadp". Each window contains its own values of dot and mark.
guide redisplay. Although this is a bit of a compromise in terms of * The flag field contains some bits that are set by commands to guide
decoupling, the full blown redisplay is just too expensive to run for * redisplay. Although this is a bit of a compromise in terms of decoupling,
every input character. * the full blown redisplay is just too expensive to run for every input
* character.
*/ */
typedef struct window { typedef struct window {
struct window *w_wndp; /* Next window */ struct window *w_wndp; /* Next window */
buffer_p w_bufp ; /* Buffer displayed in window */ struct buffer *w_bufp; /* Buffer displayed in window */
line_p w_linep ; /* Top line in the window */ line_p w_linep ; /* Top line in the window */
line_p w_dotp ; /* Line containing "." */ line_p w_dotp ; /* Line containing "." */
line_p w_markp ; /* Line containing "mark" */ line_p w_markp ; /* Line containing "mark" */
int w_doto ; /* Byte offset for "." */ int w_doto ; /* Byte offset for "." */
int w_marko ; /* Byte offset for "mark" */ int w_marko; /* Byte offset for "mark" */
int w_toprow ; /* Origin 0 top row of window */ int w_toprow ; /* Origin 0 top row of window */
int w_ntrows ; /* # of rows of text in window */ int w_ntrows ; /* # of rows of text in window */
char w_force ; /* If NZ, forcing row. */ char w_force; /* If NZ, forcing row. */
char w_flag ; /* Flags. */ char w_flag; /* Flags. */
# if COLOR #if COLOR
char w_fcolor ; /* current forground color */ char w_fcolor; /* current forground color */
char w_bcolor ; /* current background color */ char w_bcolor; /* current background color */
# endif #endif
} *window_p ; } *window_p ;
extern window_p curwp ; /* Current window */ extern window_p curwp ; /* Current window */
@ -45,34 +44,31 @@ extern window_p wheadp ; /* Head of list of windows */
#define WFMODE 0x10 /* Update mode line. */ #define WFMODE 0x10 /* Update mode line. */
#define WFCOLR 0x20 /* Needs a color change */ #define WFCOLR 0x20 /* Needs a color change */
# if SCROLLCODE #if SCROLLCODE
# define WFKILLS 0x40 /* something was deleted */ #define WFKILLS 0x40 /* something was deleted */
# define WFINS 0x80 /* something was inserted */ #define WFINS 0x80 /* something was inserted */
# endif #endif
/* Bindable functions */
BINDABLE( delwind) ;
BINDABLE( enlargewind) ;
BINDABLE( mvdnwind) ;
BINDABLE( mvupwind) ;
BINDABLE( newsize) ;
BINDABLE( newwidth) ;
BINDABLE( nextwind) ;
BINDABLE( onlywind) ;
BINDABLE( prevwind) ;
TBINDABLE( redraw) ;
TBINDABLE( reposition) ;
BINDABLE( resize) ;
BINDABLE( restwnd) ;
BINDABLE( savewnd) ;
BINDABLE( scrnextdw) ;
BINDABLE( scrnextup) ;
BINDABLE( shrinkwind) ;
BINDABLE( splitwind) ;
int reposition( int f, int n);
int redraw( int f, int n) ;
int nextwind( int f, int n) ;
int prevwind( int f, int n) ;
int mvdnwind( int f, int n) ;
int mvupwind( int f, int n) ;
int onlywind( int f, int n) ;
int delwind( int f, int n) ;
int splitwind( int f, int n) ;
int enlargewind( int f, int n) ;
int shrinkwind( int f, int n) ;
int resize( int f, int n) ;
int scrnextup( int f, int n) ;
int scrnextdw( int f, int n) ;
int savewnd( int f, int n) ;
int restwnd( int f, int n) ;
int newsize( int f, int n) ;
int newwidth( int f, int n) ;
int getwpos( void) ; int getwpos( void) ;
void cknewwindow( void) ; void cknewwindow( void) ;
window_p wpopup( void) ; /* Pop up window creation. */ window_p wpopup( void) ; /* Pop up window creation. */
#endif #endif
/* end of window.h */

160
word.c
View File

@ -1,11 +1,13 @@
/* word.c -- implements word.h */ /* word.c -- implements word.h */
#include "word.h" #include "word.h"
/* The routines in this file implement commands that work word or a /* word.c
paragraph at a time. There are all sorts of word mode commands. If I *
do any sentence mode commands, they are likely to be put in this file. * The routines in this file implement commands that work word or a
* paragraph at a time. There are all sorts of word mode commands. If I
Modified by Petri Kutvonen * do any sentence mode commands, they are likely to be put in this file.
*
* Modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -29,18 +31,18 @@ static int justflag = FALSE ; /* justify, don't fill */
static int inword( void) ; static int inword( void) ;
/* Word wrap on n-spaces. Back-over whatever precedes the point on the /* Word wrap on n-spaces. Back-over whatever precedes the point on the current
current line and stop on the first word-break or the beginning of the * line and stop on the first word-break or the beginning of the line. If we
line. If we reach the beginning of the line, jump back to the end of * reach the beginning of the line, jump back to the end of the word and start
the word and start a new line. Otherwise, break the line at the * a new line. Otherwise, break the line at the word-break, eat it, and jump
word-break, eat it, and jump back to the end of the word. * back to the end of the word.
* Returns TRUE on success, FALSE on errors.
Returns TRUE on success, FALSE on errors. *
* @f: default flag.
@f: default flag. * @n: numeric argument.
@n: numeric argument.
*/ */
BINDABLE( wrapword) { int wrapword(int f, int n)
{
int cnt; /* size of word wrapped to next line */ int cnt; /* size of word wrapped to next line */
int c; /* charector temporary */ int c; /* charector temporary */
@ -79,12 +81,11 @@ BINDABLE( wrapword) {
return TRUE; return TRUE;
} }
/* Move the cursor backward by "n" words. All of the details of motion are
/* Move the cursor backward by "n" words. All of the details of motion are * performed by the "backchar" and "forwchar" routines. Error if you try to
performed by the "backchar" and "forwchar" routines. Error if you try * move beyond the buffers.
to move beyond the buffers.
*/ */
BINDABLE( backword) { int backword( int f, int n) {
if( n < 0) if( n < 0)
return forwword( f, -n) ; return forwword( f, -n) ;
@ -105,12 +106,10 @@ BINDABLE( backword) {
return forwchar( FALSE, 1) ; return forwchar( FALSE, 1) ;
} }
/* Move the cursor forward by the specified number of words. All of the motion
/* Move the cursor forward by the specified number of words. All of the * is done by "forwchar". Error if you try and move beyond the buffer's end.
motion is done by "forwchar". Error if you try and move beyond the
buffer's end.
*/ */
BINDABLE( forwword) { int forwword( int f, int n) {
if( n < 0) if( n < 0)
return backword( f, -n) ; return backword( f, -n) ;
@ -173,41 +172,40 @@ static boolean capcapword( int n, boolean first_f, boolean rest_f) {
return TRUE ; return TRUE ;
} }
/* Move the cursor forward by the specified number of words. As you move,
/* Move the cursor forward by the specified number of words. As you move, * convert any characters to upper case. Error if you try and move beyond the
convert any characters to upper case. Error if you try and move beyond * end of the buffer. Bound to "M-U".
the end of the buffer. Bound to "M-U".
*/ */
BINDABLE( upperword) { int upperword( int f, int n) {
return capcapword( n, TRUE, TRUE) ; return capcapword( n, TRUE, TRUE) ;
} }
/* Move the cursor forward by the specified number of words. As you move /* Move the cursor forward by the specified number of words. As you move
convert characters to lower case. Error if you try and move over the * convert characters to lower case. Error if you try and move over the end of
end of the buffer. Bound to "M-L". * the buffer. Bound to "M-L".
*/ */
BINDABLE( lowerword) { int lowerword( int f, int n) {
return capcapword( n, FALSE, FALSE) ; return capcapword( n, FALSE, FALSE) ;
} }
/* Move the cursor forward by the specified number of words. As you move
/* Move the cursor forward by the specified number of words. As you move * convert the first character of the word to upper case, and subsequent
convert the first character of the word to upper case, and subsequent * characters to lower case. Error if you try and move past the end of the
characters to lower case. Error if you try and move past the end of the * buffer. Bound to "M-C".
buffer. Bound to "M-C".
*/ */
BINDABLE( capword) { int capword( int f, int n) {
return capcapword( n, TRUE, FALSE) ; return capcapword( n, TRUE, FALSE) ;
} }
/*
/* Kill forward by "n" words. Remember the location of dot. Move forward * Kill forward by "n" words. Remember the location of dot. Move forward by
by the right number of words. Put dot back where it was and issue the * the right number of words. Put dot back where it was and issue the kill
kill command for the right number of characters. With a zero argument, * command for the right number of characters. With a zero argument, just
just kill one word and no whitespace. Bound to "M-D". * kill one word and no whitespace. Bound to "M-D".
*/ */
BINDABLE( delfword) { int delfword(int f, int n)
{
line_p dotp; /* original cursor line */ line_p dotp; /* original cursor line */
int doto; /* and row */ int doto; /* and row */
int c; /* temp char */ int c; /* temp char */
@ -287,13 +285,13 @@ BINDABLE( delfword) {
return ldelete(size, TRUE); return ldelete(size, TRUE);
} }
/*
/* Kill backwards by "n" words. Move backwards by the desired number of * Kill backwards by "n" words. Move backwards by the desired number of words,
words, counting the characters. When dot is finally moved to its * counting the characters. When dot is finally moved to its resting place,
resting place, fire off the kill command. Bound to "M-Rubout" and to * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
"M-Backspace".
*/ */
BINDABLE( delbword) { int delbword(int f, int n)
{
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
/* ignore the command if there is a nonpositive argument */ /* ignore the command if there is a nonpositive argument */
@ -354,13 +352,17 @@ static int parafillnjustify( int f, int n, int justify_f) {
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
if( fillcol == 0) /* no fill column set */ if (fillcol == 0) { /* no fill column set */
return mloutfail( "No fill column set") ; mloutstr( "No fill column set") ;
return FALSE;
}
if( justify_f) { if( justify_f) {
leftmarg = getccol( FALSE) ; leftmarg = getccol( FALSE) ;
if( leftmarg + 10 > fillcol) if (leftmarg + 10 > fillcol) {
return mloutfail( "Column too narrow") ; mloutstr( "Column too narrow") ;
return FALSE;
}
justflag = justify_f ; justflag = justify_f ;
} }
@ -470,33 +472,33 @@ static int parafillnjustify( int f, int n, int justify_f) {
return TRUE; return TRUE;
} }
/*
/* Fill the current paragraph according to the current * Fill the current paragraph according to the current
* fill column * fill column
* *
* f and n - deFault flag and Numeric argument * f and n - deFault flag and Numeric argument
*/ */
BINDABLE( fillpara) { int fillpara( int f, int n) {
return parafillnjustify( f, n, FALSE) ; return parafillnjustify( f, n, FALSE) ;
} }
/* Fill the current paragraph according to the current /* Fill the current paragraph according to the current
* fill column and cursor position * fill column and cursor position
* *
* int f, n; deFault flag and Numeric argument * int f, n; deFault flag and Numeric argument
*/ */
BINDABLE( justpara) { int justpara( int f, int n) {
return parafillnjustify( f, n, TRUE) ; return parafillnjustify( f, n, TRUE) ;
} }
/*
/* delete n paragraphs starting with the current one * delete n paragraphs starting with the current one
* *
* int f default flag * int f default flag
* int n # of paras to delete * int n # of paras to delete
*/ */
BINDABLE( killpara) { int killpara(int f, int n)
{
while (n--) { /* for each paragraph to delete */ while (n--) { /* for each paragraph to delete */
/* mark out the end and beginning of the para to delete */ /* mark out the end and beginning of the para to delete */
@ -523,13 +525,15 @@ BINDABLE( killpara) {
} }
/* wordcount: count the # of words in the marked region, /*
* wordcount: count the # of words in the marked region,
* along with average word sizes, # of chars, etc, * along with average word sizes, # of chars, etc,
* and report on them. * and report on them.
* *
* int f, n; ignored numeric arguments * int f, n; ignored numeric arguments
*/ */
BINDABLE( wordcount) { int wordcount(int f, int n)
{
line_p lp; /* current line to scan */ line_p lp; /* current line to scan */
int offset; /* current char to scan */ int offset; /* current char to scan */
long size; /* size of region left to count */ long size; /* size of region left to count */
@ -587,14 +591,15 @@ BINDABLE( wordcount) {
return TRUE; return TRUE;
} }
/*
/* go back to the beginning of the current paragraph * go back to the beginning of the current paragraph
* here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
* combination to delimit the beginning of a paragraph * combination to delimit the beginning of a paragraph
* *
* int f, n; default Flag & Numeric argument * int f, n; default Flag & Numeric argument
*/ */
BINDABLE( gotobop) { int gotobop(int f, int n)
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotoeop(f, -n); return gotoeop(f, -n);
@ -624,14 +629,15 @@ BINDABLE( gotobop) {
return TRUE; return TRUE;
} }
/*
/* Go forward to the end of the current paragraph here we look for a * Go forward to the end of the current paragraph
<NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
beginning of a paragraph * combination to delimit the beginning of a paragraph
*
int f, n; default Flag & Numeric argument * int f, n; default Flag & Numeric argument
*/ */
BINDABLE( gotoeop) { int gotoeop(int f, int n)
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotobop(f, -n); return gotobop(f, -n);