basic: code review and minor refactoring.

This commit is contained in:
Renaud 2021-08-09 12:06:07 +08:00
parent 893e34b740
commit eaf516110f
2 changed files with 241 additions and 263 deletions

485
basic.c
View File

@ -1,19 +1,16 @@
/* basic.c -- implements basic.h */
#include "basic.h"
/* basic.c
*
* The routines in this file move the cursor around on the screen. They
* compute a new value for the cursor, then adjust ".". The display code
* always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
* framing, are hard.
*
* modified by Petri Kutvonen
/* The routines in this file move the cursor around on the screen. They
compute a new value for the cursor, then adjust ".". The display code
always updates the cursor location, so only moves between lines, or
functions that adjust the top line in the window and invalidate the
framing, are hard.
modified by Petri Kutvonen
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "input.h"
@ -22,340 +19,322 @@
#include "terminal.h"
#include "window.h"
#define CVMVAS 1 /* arguments to page forward/back in pages */
#define CVMVAS 1 /* arguments to page forward/back in pages */
int overlap = 0 ; /* $overlap: line overlap in forw/back page */
int curgoal ; /* $target: Goal for C-P, C-N */
int overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */
int curgoal ; /* Goal for C-P, C-N */
/*
* 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".
/* 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) {
int col ;
unsigned idx ;
const unsigned len = llength( dlp) ;
int col = 0 ;
const unsigned len = llength( dlp) ;
unsigned idx = 0 ;
while( idx < len) {
unicode_t c ;
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
col = 0 ;
idx = 0 ;
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 */
if( c == '\t')
col += tabwidth - col % tabwidth ;
else if( c < 0x20 || c == 0x7F) /* ^x */
col += 2 ;
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 */
}
/* Take tabs, ^X and \xx hex characters into account */
if( c == '\t')
col += tabwidth - col % tabwidth ;
else if( c < 0x20 || c == 0x7F)
col += 2 ;
else if( c >= 0x80 && c <= 0xA0)
col += 3 ;
else
col += 1 ;
if( col > curgoal)
break ;
else
idx += width ;
}
if( col > curgoal)
break ;
idx += width ;
}
return idx ;
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. */
boolean gotobol( int f, int n) {
curwp->w_doto = 0 ;
return TRUE ;
curwp->w_doto = 0 ;
return TRUE ;
}
/*
* Move the cursor to the end of the current line of active window.
*/
/* Move the cursor to the end of the current line of active window. */
boolean gotoeol( int f, int n) {
curwp->w_doto = llength( curwp->w_dotp) ;
return TRUE ;
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-<".
/* 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-<".
*/
boolean gotobob( int f, int n) {
curwp->w_dotp = lforw( curbp->b_linep) ;
curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ;
return TRUE ;
curwp->w_dotp = lforw( curbp->b_linep) ;
curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ;
return TRUE ;
}
/*
* Move to the end of the buffer. Dot is always put at the end of the file
* (ZJ). The standard screen code does most of the hard parts of update.
* Bound to "M->".
/* Move to the end of the buffer. Dot is always put at the end of the file
(ZJ). The standard screen code does most of the hard parts of update.
Bound to "M->".
*/
boolean gotoeob( int f, int n) {
curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ;
return TRUE ;
curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ;
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.
/* 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 ;
assert( f == TRUE || n == 1) ;
if( n < 0)
return backline( f, -n) ;
if (n < 0)
return backline(f, -n);
/* if we are on the last line as we start....fail the command */
if( n && curwp->w_dotp == curbp->b_linep)
return FALSE ;
/* 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) ;
/* 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 ;
/* flag this command as a line move */
thisflag |= CFCPCN;
/* and move the point down */
line_p dlp = curwp->w_dotp ;
while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ;
n -= 1 ;
}
/* 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 ;
/* 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".
/* 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 (n < 0)
return forwline(f, -n);
/* if we are on the first line as we start....fail the command */
if( n && lback( curwp->w_dotp) == curbp->b_linep)
return FALSE ;
/* 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) ;
/* 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 ;
/* flag this command as a line move */
thisflag |= CFCPCN;
/* and move the point up */
line_p dlp = curwp->w_dotp ;
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n -= 1 ;
}
/* 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 ;
/* 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.
/* Move to a particular line.
*
* @n: The specified line position at the current buffer.
*/
int gotoline( int f, int n) {
/* Get an argument if one doesnt exist. */
if( f == FALSE) {
int status ;
char *arg ; /* Buffer to hold argument. */
BINDABLE( gotoline) {
/* Get an argument if one doesn't exist. */
if( f == FALSE) {
char *arg ; /* Buffer to hold argument. */
status = newmlarg( &arg, "Line to GOTO: ", 0) ;
if( status != TRUE) {
mloutstr( "(Aborted)") ;
return status ;
}
int status = newmlarg( &arg, "goto-line: ", 0) ;
if( status != TRUE)
return status ;
n = atoi( arg) ;
free( arg) ;
}
n = atoi( arg) ;
free( arg) ;
f = TRUE ;
}
/* Handle the case where the user may be passed something like this:
* em filename +
* In this case we just go to the end of the buffer.
*/
if (n == 0)
return gotoeob(f, n);
/* Handle the case where the user may be passed something like this:
* ue filename +
* In this case we just go to the end of the buffer.
*/
if( n == 0)
return gotoeob( f, n) ;
/* If a bogus argument was passed, then returns false. */
if (n < 0)
return FALSE;
/* If a bogus argument was passed, then returns false. */
if( n < 0)
return FALSE ;
/* First, we go to the begin of the buffer. */
gotobob(f, n);
return (n == 1) ? TRUE : forwline( f, n - 1) ;
/* First, we go to the begin of the buffer. */
gotobob( f, n) ;
return (n == 1) ? TRUE : forwline( TRUE, n - 1) ;
}
/*
* 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 is
* the overlap; this value is the default overlap value in ITS EMACS. Because
* this zaps the top line in the display window, we have to do a hard update.
/* 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
is the overlap; this value is the default overlap value in ITS EMACS.
Because this zaps the top line in the display window, we have to do a
hard update.
*/
boolean forwpage( int f, int n) {
line_p lp ;
line_p lp ;
if (f == FALSE) {
if( f == FALSE) {
#if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll == FALSE */
if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ;
else
n = curwp->w_ntrows - overlap;
else
if (term.t_scroll != NULL) /* $scroll == FALSE */
if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ;
else
n = curwp->w_ntrows - overlap;
else
#endif
n = curwp->w_ntrows - 2; /* Default scroll. */
n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Forget the overlap. */
n = 1; /* If tiny window. */
} else if (n < 0)
return backpage(f, -n);
if (n <= 0) /* Forget the overlap. */
n = 1; /* If tiny window. */
} else if( n < 0)
return backpage(f, -n);
#if CVMVAS
else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */
else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */
#endif
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ;
while( n && lp != curbp->b_linep) {
lp = lforw( lp) ;
n -= 1 ;
}
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ;
while( n && lp != curbp->b_linep) {
lp = lforw( lp) ;
n -= 1 ;
}
/* curwp->w_linep = lp; */
curwp->w_dotp = lp;
curwp->w_doto = 0;
reposition( TRUE, 0) ;
/* curwp->w_linep = lp; */
curwp->w_dotp = lp;
curwp->w_doto = 0;
reposition( TRUE, 0) ;
#if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS;
curwp->w_flag |= WFHARD | WFKILLS;
#else
curwp->w_flag |= WFHARD;
curwp->w_flag |= WFHARD;
#endif
return TRUE;
return TRUE ;
}
/*
* 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 ITS
* EMACS manual. Bound to "M-V". We do a hard update for exactly the same
* reason.
/* 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
ITS EMACS manual. Bound to "M-V". We do a hard update for exactly the
same reason.
*/
boolean backpage( int f, int n) {
line_p lp ;
line_p lp ;
if (f == FALSE) { /* interactive, default n = 1 supplied */
/* in interactive mode, first move dot to top of window */
if( curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = curwp->w_linep ;
curwp->w_doto = 0 ;
/* curwp->w_flag |= WFMOVE ; */
return TRUE ;
}
if( f == FALSE) { /* interactive, default n = 1 supplied */
/* in interactive mode, first move dot to top of window */
if( curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = curwp->w_linep ;
curwp->w_doto = 0 ;
/* curwp->w_flag |= WFMOVE ; */
return TRUE ;
}
#if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll != FALSE */
if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ;
else
n = curwp->w_ntrows - overlap;
else
if (term.t_scroll != NULL) /* $scroll != FALSE */
if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ;
else
n = curwp->w_ntrows - overlap;
else
#endif
n = curwp->w_ntrows - 2; /* Default scroll. */
n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Don't blow up if the. */
n = 1; /* Window is tiny. */
} else if (n < 0)
return forwpage(f, -n);
if (n <= 0) /* Don't blow up if the. */
n = 1; /* Window is tiny. */
} else if (n < 0)
return forwpage(f, -n);
#if CVMVAS
else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */
else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */
#endif
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ;
while( n && lback( lp) != curbp->b_linep) {
lp = lback( lp) ;
n -= 1 ;
}
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ;
while( n && lback( lp) != curbp->b_linep) {
lp = lback( lp) ;
n -= 1 ;
}
/* curwp->w_linep = lp; */
curwp->w_dotp = lp;
curwp->w_doto = 0;
reposition( TRUE, (f == FALSE) ? 1 : 0) ;
/* curwp->w_linep = lp; */
curwp->w_dotp = lp;
curwp->w_doto = 0;
reposition( TRUE, (f == FALSE) ? 1 : 0) ;
#if SCROLLCODE
curwp->w_flag |= WFHARD | WFINS;
curwp->w_flag |= WFHARD | WFINS;
#else
curwp->w_flag |= WFHARD;
curwp->w_flag |= WFHARD;
#endif
return TRUE;
return TRUE;
}
/*
* Set the mark in the current window to the value of "." in the window. No
* errors are possible. Bound to "M-.".
/* Set the mark in the current window to the value of "." in the window.
No errors are possible. Bound to M-. set-mark.
*/
boolean setmark( int f, int n) {
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
mloutstr( "(Mark set)") ;
return TRUE ;
curwp->w_markp = curwp->w_dotp ;
curwp->w_marko = curwp->w_doto ;
mloutstr( "(Mark set)") ;
return TRUE ;
}
/*
* Swap the values of "." and "mark" in the current window. This is pretty
* 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".
/* Swap the values of "." and "mark" in the current window. If no mark as
been previously set, set it. Bound to C-X C-X exchange-point-and-mark.
*/
boolean swapmark( int f, int n) {
line_p odotp ;
int odoto;
line_p odotp = curwp->w_dotp ;
int odoto = curwp->w_doto ;
if( curwp->w_markp) {
curwp->w_dotp = curwp->w_markp ;
curwp->w_doto = curwp->w_marko ;
curwp->w_flag |= WFMOVE ;
}
if( curwp->w_markp == NULL) {
mloutstr( "No mark in this window") ;
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;
curwp->w_markp = odotp ;
curwp->w_marko = odoto ;
return TRUE ;
}
/* end of basic.c */

19
basic.h
View File

@ -3,24 +3,23 @@
#ifndef _BASIC_H_
#define _BASIC_H_
#include "retcode.h"
#include "names.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)
** default to 0
*/
#define DEFAULT_OVERLAP 0
extern int overlap ; /* line overlap in forw/back page */
/* $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)
default to 0
*/
extern int overlap ; /* $overlap: line overlap in forw/back page */
/* $target (== curgoal) is the column target when doing line move */
extern int curgoal ; /* Goal for C-P previous-line, C-N next-line */
extern int curgoal ; /* $target: Goal for C-P previous-line, C-N next-line */
/* Bindable functions */
boolean gotobol( int f, int n) ;
boolean gotoeol( int f, int n) ;
int gotoline( int f, int n) ;
BINDABLE( gotoline) ;
boolean gotobob( int f, int n) ;
boolean gotoeob( int f, int n) ;
boolean forwline( int f, int n) ;